Merge remote-tracking branch 'origin/dev' into portal-api

This commit is contained in:
Alexandre Aubin 2023-07-17 18:56:05 +02:00
commit f69f87fa65
25 changed files with 1519 additions and 979 deletions

View file

@ -37,8 +37,6 @@ full-tests:
- yunohost tools postinstall -d domain.tld -u syssa -F 'Syssa Mine' -p the_password --ignore-dyndns --force-diskspace - yunohost tools postinstall -d domain.tld -u syssa -F 'Syssa Mine' -p the_password --ignore-dyndns --force-diskspace
script: script:
- python3 -m pytest --cov=yunohost tests/ src/tests/ --junitxml=report.xml - python3 -m pytest --cov=yunohost tests/ src/tests/ --junitxml=report.xml
- cd tests
- bash test_helpers.sh
needs: needs:
- job: build-yunohost - job: build-yunohost
artifacts: true artifacts: true
@ -64,9 +62,9 @@ test-helpers:
script: script:
- cd tests - cd tests
- bash test_helpers.sh - bash test_helpers.sh
only: # only:
changes: # changes:
- helpers/* # - helpers/*
test-domains: test-domains:
extends: .test-stage extends: .test-stage

View file

@ -1,77 +1,34 @@
#!/bin/bash #!/usr/bin/env python3
set -e import sys
set -u import requests
import json
PASTE_URL="https://paste.yunohost.org" SERVER_URL = "https://paste.yunohost.org"
TIMEOUT = 3
_die() { def create_snippet(data):
printf "Error: %s\n" "$*" try:
exit 1 url = SERVER_URL + "/documents"
} response = requests.post(url, data=data.encode('utf-8'), timeout=TIMEOUT)
response.raise_for_status()
dockey = json.loads(response.text)['key']
return SERVER_URL + "/raw/" + dockey
except requests.exceptions.RequestException as e:
print("\033[31mError: {}\033[0m".format(e))
sys.exit(1)
check_dependencies() {
curl -V > /dev/null 2>&1 || _die "This script requires curl."
}
paste_data() { def main():
json=$(curl -X POST -s -d "$1" "${PASTE_URL}/documents") output = sys.stdin.read()
[[ -z "$json" ]] && _die "Unable to post the data to the server."
key=$(echo "$json" \ if not output:
| python3 -c 'import json,sys;o=json.load(sys.stdin);print(o["key"])' \ print("\033[31mError: No input received from stdin.\033[0m")
2>/dev/null) sys.exit(1)
[[ -z "$key" ]] && _die "Unable to parse the server response."
echo "${PASTE_URL}/${key}" url = create_snippet(output)
}
usage() { print("\033[32mURL: {}\033[0m".format(url))
printf "Usage: ${0} [OPTION]...
Read from input stream and paste the data to the YunoHost if __name__ == "__main__":
Haste server. main()
For example, to paste the output of the YunoHost diagnosis, you
can simply execute the following:
yunohost diagnosis show | ${0}
It will return the URL where you can access the pasted data.
Options:
-h, --help show this help message and exit
"
}
main() {
# parse options
while (( ${#} )); do
case "${1}" in
--help|-h)
usage
exit 0
;;
*)
echo "Unknown parameter detected: ${1}" >&2
echo >&2
usage >&2
exit 1
;;
esac
shift 1
done
# check input stream
read -t 0 || {
echo -e "Invalid usage: No input is provided.\n" >&2
usage
exit 1
}
paste_data "$(cat)"
}
check_dependencies
main "${@}"

View file

@ -38,14 +38,26 @@ ssl_prefer_server_ciphers = no
############################################################################### ###############################################################################
# Regular Yunohost accounts
passdb { passdb {
args = /etc/dovecot/dovecot-ldap.conf args = /etc/dovecot/dovecot-ldap.conf
driver = ldap driver = ldap
} }
# Internally, allow authentication from apps system user who have "enable_email = true"
passdb {
driver = passwd-file
args = /etc/dovecot/app-senders-passwd
}
userdb { userdb {
args = /etc/dovecot/dovecot-ldap.conf
driver = ldap driver = ldap
args = /etc/dovecot/dovecot-ldap.conf
}
userdb {
driver = passwd-file
args = /etc/dovecot/app-senders-passwd
} }
protocol imap { protocol imap {

View file

@ -56,7 +56,7 @@ server {
ssl_stapling on; ssl_stapling on;
ssl_stapling_verify on; ssl_stapling_verify on;
ssl_trusted_certificate /etc/yunohost/certs/{{ domain }}/crt.pem; ssl_trusted_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
resolver 127.0.0.1 127.0.1.1 valid=300s; resolver 1.1.1.1 9.9.9.9 valid=300s;
resolver_timeout 5s; resolver_timeout 5s;
{% endif %} {% endif %}
@ -115,7 +115,7 @@ server {
ssl_stapling on; ssl_stapling on;
ssl_stapling_verify on; ssl_stapling_verify on;
ssl_trusted_certificate /etc/yunohost/certs/{{ domain }}/crt.pem; ssl_trusted_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
resolver 127.0.0.1 127.0.1.1 valid=300s; resolver 1.1.1.1 9.9.9.9 valid=300s;
resolver_timeout 5s; resolver_timeout 5s;
{% endif %} {% endif %}

View file

@ -107,7 +107,12 @@ virtual_alias_domains =
virtual_minimum_uid = 100 virtual_minimum_uid = 100
virtual_uid_maps = static:vmail virtual_uid_maps = static:vmail
virtual_gid_maps = static:mail virtual_gid_maps = static:mail
smtpd_sender_login_maps= ldap:/etc/postfix/ldap-accounts.cf smtpd_sender_login_maps=
# Regular Yunohost accounts
ldap:/etc/postfix/ldap-accounts.cf,
# Extra maps for app system users who need to send emails
hash:/etc/postfix/app_senders_login_maps
# Dovecot LDA # Dovecot LDA
virtual_transport = dovecot virtual_transport = dovecot

View file

@ -64,7 +64,7 @@ PasswordAuthentication no
{% endif %} {% endif %}
# Post-login stuff # Post-login stuff
Banner /etc/issue.net # Banner none
PrintMotd no PrintMotd no
PrintLastLog yes PrintLastLog yes
ClientAliveInterval 60 ClientAliveInterval 60

16
debian/changelog vendored
View file

@ -1,3 +1,19 @@
yunohost (11.2) stable; urgency=low
- dyndns: add support for recovery passwords ([#1475](https://github.com/YunoHost/yunohost/pull/1475))
- mail/apps: allow system users to auth on the mail stack and send emails ([#815](https://github.com/YunoHost/yunohost/pull/815))
- nginx: fix OCSP stapling errors ([#1543](https://github.com/YunoHost/yunohost/pull/1534))
- ssh: disable banner by default ([#1605](https://github.com/YunoHost/yunohost/pull/1605))
- configpanels: another partial refactoring of config panels / questions, paving the way for Pydantic ([#1676](https://github.com/YunoHost/yunohost/pull/1676))
- misc: rewrite the `yunopaste` tool ([#1667](https://github.com/YunoHost/yunohost/pull/1667))
- apps: simplify the use of `ynh_add_fpm_config` ([#1684](https://github.com/YunoHost/yunohost/pull/1684))
- apps: in ynh_systemd_action, check the actual timestamp when checking for timeout, because for some reason journalctl may take a ridiculous amount of time to run (f3eef43d)
- i18n: Translations updated for German, Japanese
Thanks to all contributors <3 ! (André Théo LAURET, axolotle, Christian Wehrli, Éric Gaspar, ljf, motcha, theo-is-taken)
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 17 Jul 2023 16:14:58 +0200
yunohost (11.1.22) stable; urgency=low yunohost (11.1.22) stable; urgency=low
- security: replace $http_host by $host in nginx conf, cf https://github.com/yandex/gixy/blob/master/docs/en/plugins/hostspoofing.md / Credit to A.Wolski (3957b10e) - security: replace $http_host by $host in nginx conf, cf https://github.com/yandex/gixy/blob/master/docs/en/plugins/hostspoofing.md / Credit to A.Wolski (3957b10e)

View file

@ -7,33 +7,44 @@ YNH_PHP_VERSION=${YNH_PHP_VERSION:-$YNH_DEFAULT_PHP_VERSION}
# Create a dedicated PHP-FPM config # Create a dedicated PHP-FPM config
# #
# usage 1: ynh_add_fpm_config [--phpversion=7.X] [--use_template] [--package=packages] [--dedicated_service] # usage: ynh_add_fpm_config
# | arg: -v, --phpversion= - Version of PHP to use.
# | arg: -t, --use_template - Use this helper in template mode.
# | arg: -p, --package= - Additionnal PHP packages to install
# | arg: -d, --dedicated_service - Use a dedicated PHP-FPM service instead of the common one.
# #
# ----------------------------------------------------------------------------- # Case 1 (recommended) : your provided a snippet conf/extra_php-fpm.conf
# #
# usage 2: ynh_add_fpm_config [--phpversion=7.X] --usage=usage --footprint=footprint [--package=packages] [--dedicated_service] # The actual PHP configuration will be automatically generated,
# | arg: -v, --phpversion= - Version of PHP to use. # and your extra_php-fpm.conf will be appended (typically contains PHP upload limits)
# | arg: -f, --footprint= - Memory footprint of the service (low/medium/high). #
# The resulting configuration will be deployed to the appropriate place, /etc/php/$phpversion/fpm/pool.d/$app.conf
#
# Performance-related options in the PHP conf, such as :
# pm.max_children, pm.start_servers, pm.min_spare_servers pm.max_spare_servers
# are computed from two parameters called "usage" and "footprint" which can be set to low/medium/high. (cf details below)
#
# If you wish to tweak those, please initialize the settings `fpm_usage` and `fpm_footprint`
# *prior* to calling this helper. Otherwise, "low" will be used as a default for both values.
#
# Otherwise, if you want the user to have control over these, we encourage to create a config panel
# (which should ultimately be standardized by the core ...)
#
# Case 2 (deprecate) : you provided an entire conf/php-fpm.conf
#
# The configuration will be hydrated, replacing __FOOBAR__ placeholders with $foobar values, etc.
#
# The resulting configuration will be deployed to the appropriate place, /etc/php/$phpversion/fpm/pool.d/$app.conf
#
# ----------------------
#
# fpm_footprint: Memory footprint of the service (low/medium/high).
# low - Less than 20 MB of RAM by pool. # low - Less than 20 MB of RAM by pool.
# medium - Between 20 MB and 40 MB of RAM by pool. # medium - Between 20 MB and 40 MB of RAM by pool.
# high - More than 40 MB of RAM by pool. # high - More than 40 MB of RAM by pool.
# Or specify exactly the footprint, the load of the service as MB by pool instead of having a standard value. # N - Or you can specify a quantitative footprint as MB by pool (use watch -n0.5 ps -o user,cmd,%cpu,rss -u APP)
# To have this value, use the following command and stress the service.
# watch -n0.5 ps -o user,cmd,%cpu,rss -u APP
# #
# | arg: -u, --usage= - Expected usage of the service (low/medium/high). # fpm_usage: Expected usage of the service (low/medium/high).
# low - Personal usage, behind the SSO. # low - Personal usage, behind the SSO.
# medium - Low usage, few people or/and publicly accessible. # medium - Low usage, few people or/and publicly accessible.
# high - High usage, frequently visited website. # high - High usage, frequently visited website.
# #
# | arg: -p, --package= - Additionnal PHP packages to install for a specific version of PHP
# | arg: -d, --dedicated_service - Use a dedicated PHP-FPM service instead of the common one.
#
#
# The footprint of the service will be used to defined the maximum footprint we can allow, which is half the maximum RAM. # The footprint of the service will be used to defined the maximum footprint we can allow, which is half the maximum RAM.
# So it will be used to defined 'pm.max_children' # So it will be used to defined 'pm.max_children'
# A lower value for the footprint will allow more children for 'pm.max_children'. And so for # A lower value for the footprint will allow more children for 'pm.max_children'. And so for
@ -59,10 +70,9 @@ YNH_PHP_VERSION=${YNH_PHP_VERSION:-$YNH_DEFAULT_PHP_VERSION}
ynh_add_fpm_config() { ynh_add_fpm_config() {
local _globalphpversion=${phpversion-:} local _globalphpversion=${phpversion-:}
# Declare an array to define the options of this helper. # Declare an array to define the options of this helper.
local legacy_args=vtufpd local legacy_args=vufpd
local -A args_array=([v]=phpversion= [t]=use_template [u]=usage= [f]=footprint= [p]=package= [d]=dedicated_service) local -A args_array=([v]=phpversion= [u]=usage= [f]=footprint= [p]=package= [d]=dedicated_service)
local phpversion local phpversion
local use_template
local usage local usage
local footprint local footprint
local package local package
@ -72,11 +82,28 @@ ynh_add_fpm_config() {
package=${package:-} package=${package:-}
# The default behaviour is to use the template. # The default behaviour is to use the template.
use_template="${use_template:-1}" local autogenconf=false
usage="${usage:-}" usage="${usage:-}"
footprint="${footprint:-}" footprint="${footprint:-}"
if [ -n "$usage" ] || [ -n "$footprint" ]; then if [ -n "$usage" ] || [ -n "$footprint" ] || [[ -e $YNH_APP_BASEDIR/conf/extra_php-fpm.conf ]]; then
use_template=0 autogenconf=true
# If no usage provided, default to the value existing in setting ... or to low
local fpm_usage_in_setting=$(ynh_app_setting_get --app=$app --key=fpm_usage)
if [ -z "$usage" ]
then
usage=${fpm_usage_in_setting:-low}
ynh_app_setting_set --app=$app --key=fpm_usage --value=$usage
fi
# If no footprint provided, default to the value existing in setting ... or to low
local fpm_footprint_in_setting=$(ynh_app_setting_get --app=$app --key=fpm_footprint)
if [ -z "$footprint" ]
then
footprint=${fpm_footprint_in_setting:-low}
ynh_app_setting_set --app=$app --key=fpm_footprint --value=$footprint
fi
fi fi
# Do not use a dedicated service by default # Do not use a dedicated service by default
dedicated_service=${dedicated_service:-0} dedicated_service=${dedicated_service:-0}
@ -111,6 +138,7 @@ ynh_add_fpm_config() {
fi fi
if [ $dedicated_service -eq 1 ]; then if [ $dedicated_service -eq 1 ]; then
ynh_print_warn --message "Argument --dedicated_service of ynh_add_fpm_config is deprecated and to be removed in the future"
local fpm_service="${app}-phpfpm" local fpm_service="${app}-phpfpm"
local fpm_config_dir="/etc/php/$phpversion/dedicated-fpm" local fpm_config_dir="/etc/php/$phpversion/dedicated-fpm"
else else
@ -141,7 +169,7 @@ ynh_add_fpm_config() {
fi fi
fi fi
if [ $use_template -eq 1 ]; then if [ $autogenconf == "false" ]; then
# Usage 1, use the template in conf/php-fpm.conf # Usage 1, use the template in conf/php-fpm.conf
local phpfpm_path="$YNH_APP_BASEDIR/conf/php-fpm.conf" local phpfpm_path="$YNH_APP_BASEDIR/conf/php-fpm.conf"
# Make sure now that the template indeed exists # Make sure now that the template indeed exists
@ -149,10 +177,6 @@ ynh_add_fpm_config() {
else else
# Usage 2, generate a PHP-FPM config file with ynh_get_scalable_phpfpm # Usage 2, generate a PHP-FPM config file with ynh_get_scalable_phpfpm
# Store settings
ynh_app_setting_set --app=$app --key=fpm_footprint --value=$footprint
ynh_app_setting_set --app=$app --key=fpm_usage --value=$usage
# Define the values to use for the configuration of PHP. # Define the values to use for the configuration of PHP.
ynh_get_scalable_phpfpm --usage=$usage --footprint=$footprint ynh_get_scalable_phpfpm --usage=$usage --footprint=$footprint

View file

@ -128,6 +128,7 @@ ynh_systemd_action() {
if [[ -n "${line_match:-}" ]]; then if [[ -n "${line_match:-}" ]]; then
set +x set +x
local i=0 local i=0
local starttime=$(date +%s)
for i in $(seq 1 $timeout); do for i in $(seq 1 $timeout); do
# Read the log until the sentence is found, that means the app finished to start. Or run until the timeout # Read the log until the sentence is found, that means the app finished to start. Or run until the timeout
if [ "$log_path" == "systemd" ]; then if [ "$log_path" == "systemd" ]; then
@ -145,6 +146,14 @@ ynh_systemd_action() {
if [ $i -eq 30 ]; then if [ $i -eq 30 ]; then
echo "(this may take some time)" >&2 echo "(this may take some time)" >&2
fi fi
# Also check the timeout using actual timestamp, because sometimes for some reason,
# journalctl may take a huge time to run, and we end up waiting literally an entire hour
# instead of 5 min ...
if [[ "$(( $(date +%s) - $starttime))" -gt "$timeout" ]]
then
i=$timeout
break
fi
sleep 1 sleep 1
done done
set -x set -x

View file

@ -80,6 +80,8 @@ do_post_regen() {
postmap -F hash:/etc/postfix/sni postmap -F hash:/etc/postfix/sni
python3 -c 'from yunohost.app import regen_mail_app_user_config_for_dovecot_and_postfix as r; r(only="postfix")'
[[ -z "$regen_conf_files" ]] \ [[ -z "$regen_conf_files" ]] \
|| { systemctl restart postfix && systemctl restart postsrsd; } || { systemctl restart postfix && systemctl restart postsrsd; }

View file

@ -53,6 +53,8 @@ do_post_regen() {
chown root:mail /var/mail chown root:mail /var/mail
chmod 1775 /var/mail chmod 1775 /var/mail
python3 -c 'from yunohost.app import regen_mail_app_user_config_for_dovecot_and_postfix as r; r(only="dovecot")'
[ -z "$regen_conf_files" ] && exit 0 [ -z "$regen_conf_files" ] && exit 0
# compile sieve script # compile sieve script

View file

@ -23,16 +23,16 @@
"backup_archive_name_unknown": "Unbekanntes lokale Datensicherung mit Namen '{name}' gefunden", "backup_archive_name_unknown": "Unbekanntes lokale Datensicherung mit Namen '{name}' gefunden",
"backup_archive_open_failed": "Kann Sicherungsarchiv nicht öfnen", "backup_archive_open_failed": "Kann Sicherungsarchiv nicht öfnen",
"backup_cleaning_failed": "Temporäres Sicherungsverzeichnis konnte nicht geleert werden", "backup_cleaning_failed": "Temporäres Sicherungsverzeichnis konnte nicht geleert werden",
"backup_created": "Datensicherung komplett", "backup_created": "Datensicherung vollständig: {name}",
"backup_delete_error": "Pfad '{path}' konnte nicht gelöscht werden", "backup_delete_error": "Pfad '{path}' konnte nicht gelöscht werden",
"backup_deleted": "Backup wurde entfernt", "backup_deleted": "Backup gelöscht: {name}",
"backup_hook_unknown": "Der Datensicherungshook '{hook}' unbekannt", "backup_hook_unknown": "Der Datensicherungshook '{hook}' unbekannt",
"backup_nothings_done": "Keine Änderungen zur Speicherung", "backup_nothings_done": "Keine Änderungen zur Speicherung",
"backup_output_directory_forbidden": "Wähle ein anderes Ausgabeverzeichnis. Datensicherungen können nicht in /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var oder in Unterordnern von /home/yunohost.backup/archives erstellt werden", "backup_output_directory_forbidden": "Wähle ein anderes Ausgabeverzeichnis. Datensicherungen können nicht in /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var oder in Unterordnern von /home/yunohost.backup/archives erstellt werden",
"backup_output_directory_not_empty": "Der gewählte Ausgabeordner sollte leer sein", "backup_output_directory_not_empty": "Der gewählte Ausgabeordner sollte leer sein",
"backup_output_directory_required": "Für die Datensicherung muss ein Zielverzeichnis angegeben werden", "backup_output_directory_required": "Für die Datensicherung muss ein Zielverzeichnis angegeben werden",
"backup_running_hooks": "Datensicherunghook wird ausgeführt...", "backup_running_hooks": "Datensicherunghook wird ausgeführt...",
"custom_app_url_required": "Du musst eine URL angeben, um deine benutzerdefinierte App {app} zu aktualisieren", "custom_app_url_required": "Sie müssen eine URL angeben, um Ihre benutzerdefinierte App {app} zu aktualisieren",
"domain_cert_gen_failed": "Zertifikat konnte nicht erzeugt werden", "domain_cert_gen_failed": "Zertifikat konnte nicht erzeugt werden",
"domain_created": "Domäne erstellt", "domain_created": "Domäne erstellt",
"domain_creation_failed": "Konnte Domäne nicht erzeugen", "domain_creation_failed": "Konnte Domäne nicht erzeugen",
@ -67,11 +67,11 @@
"mail_forward_remove_failed": "Die Weiterleitungs-E-Mail '{mail}' konnte nicht gelöscht werden", "mail_forward_remove_failed": "Die Weiterleitungs-E-Mail '{mail}' konnte nicht gelöscht werden",
"main_domain_change_failed": "Die Hauptdomain konnte nicht geändert werden", "main_domain_change_failed": "Die Hauptdomain konnte nicht geändert werden",
"main_domain_changed": "Die Hauptdomain wurde geändert", "main_domain_changed": "Die Hauptdomain wurde geändert",
"pattern_backup_archive_name": "Es muss ein gültiger Dateiname mit maximal 30 Zeichen sein, nur alphanumerische Zeichen und -_.", "pattern_backup_archive_name": "Muss ein gültiger Dateiname mit maximal 30 Zeichen sein, ausschliesslich alphanumerische Zeichen und -_.",
"pattern_domain": "Muss ein gültiger Domainname sein (z.B. meine-domain.org)", "pattern_domain": "Muss ein gültiger Domainname sein (z.B. meine-domain.org)",
"pattern_email": "Es muss sich um eine gültige E-Mail-Adresse handeln, ohne '+'-Symbol (z. B. name@domäne.de)", "pattern_email": "Es muss sich um eine gültige E-Mail-Adresse handeln, ohne '+'-Symbol (z. B. name@domäne.de)",
"pattern_firstname": "Muss ein gültiger Vorname sein", "pattern_firstname": "Muss ein gültiger Vorname sein (mindestens 3 Zeichen)",
"pattern_lastname": "Muss ein gültiger Nachname sein", "pattern_lastname": "Muss ein gültiger Nachname sein (mindestens 3 Zeichen)",
"pattern_mailbox_quota": "Es muss eine Größe mit dem Suffix b/k/M/G/T sein oder 0 um kein Kontingent zu haben", "pattern_mailbox_quota": "Es muss eine Größe mit dem Suffix b/k/M/G/T sein oder 0 um kein Kontingent zu haben",
"pattern_password": "Muss mindestens drei Zeichen lang sein", "pattern_password": "Muss mindestens drei Zeichen lang sein",
"pattern_port_or_range": "Muss ein valider Port (z.B. 0-65535) oder ein Bereich (z.B. 100:200) sein", "pattern_port_or_range": "Muss ein valider Port (z.B. 0-65535) oder ein Bereich (z.B. 100:200) sein",
@ -79,11 +79,11 @@
"port_already_closed": "Der Port {port} wurde bereits für {ip_version} Verbindungen geschlossen", "port_already_closed": "Der Port {port} wurde bereits für {ip_version} Verbindungen geschlossen",
"port_already_opened": "Der Port {port} wird bereits von {ip_version} benutzt", "port_already_opened": "Der Port {port} wird bereits von {ip_version} benutzt",
"restore_already_installed_app": "Eine Applikation mit der ID '{app}' ist bereits installiert", "restore_already_installed_app": "Eine Applikation mit der ID '{app}' ist bereits installiert",
"restore_cleaning_failed": "Das temporäre Dateiverzeichnis für Systemrestaurierung konnte nicht gelöscht werden", "restore_cleaning_failed": "Das temporäre Dateiverzeichnis für die Systemwiederherstellung konnte nicht gelöscht werden",
"restore_complete": "Vollständig wiederhergestellt", "restore_complete": "Vollständig wiederhergestellt",
"restore_confirm_yunohost_installed": "Möchtest du die Wiederherstellung wirklich starten? [{answers}]", "restore_confirm_yunohost_installed": "Möchten Sie die Wiederherstellung wirklich starten? [{answers}]",
"restore_failed": "System konnte nicht wiederhergestellt werden", "restore_failed": "System konnte nicht wiederhergestellt werden",
"restore_hook_unavailable": "Das Wiederherstellungsskript für '{part}' steht weder in deinem System noch im Archiv zur Verfügung", "restore_hook_unavailable": "Das Wiederherstellungsskript für '{part}' steht weder in Ihrem System noch im Archiv zur Verfügung",
"restore_nothings_done": "Nichts wurde wiederhergestellt", "restore_nothings_done": "Nichts wurde wiederhergestellt",
"restore_running_app_script": "App '{app}' wird wiederhergestellt...", "restore_running_app_script": "App '{app}' wird wiederhergestellt...",
"restore_running_hooks": "Wiederherstellung wird gestartet...", "restore_running_hooks": "Wiederherstellung wird gestartet...",
@ -140,8 +140,8 @@
"dyndns_key_not_found": "DNS-Schlüssel für die Domain wurde nicht gefunden", "dyndns_key_not_found": "DNS-Schlüssel für die Domain wurde nicht gefunden",
"dyndns_no_domain_registered": "Keine Domain mit DynDNS registriert", "dyndns_no_domain_registered": "Keine Domain mit DynDNS registriert",
"mailbox_used_space_dovecot_down": "Der Dovecot-Mailbox-Dienst muss aktiv sein, wenn du den von der Mailbox belegten Speicher abrufen willst", "mailbox_used_space_dovecot_down": "Der Dovecot-Mailbox-Dienst muss aktiv sein, wenn du den von der Mailbox belegten Speicher abrufen willst",
"certmanager_attempt_to_replace_valid_cert": "Du versuchst gerade eine richtiges und gültiges Zertifikat der Domain {domain} zu überschreiben! (Benutze --force , um diese Nachricht zu umgehen)", "certmanager_attempt_to_replace_valid_cert": "Sie versuchen gerade ein gutes und gültiges Zertifikat der Domäne {domain} zu überschreiben! (Benutzen Sie --force , um diese Nachricht zu umgehen)",
"certmanager_domain_cert_not_selfsigned": "Das Zertifikat der Domain {domain} ist kein selbstsigniertes Zertifikat. Bist du sich sicher, dass du es ersetzen willst? (Benutze dafür '--force')", "certmanager_domain_cert_not_selfsigned": "Das Zertifikat der Domäne {domain} ist kein selbstsigniertes Zertifikat. Sind Sie sicher, dass Sie es ersetzen möchten? (Verwenden Sie dafür '--force')",
"certmanager_certificate_fetching_or_enabling_failed": "Die Aktivierung des neuen Zertifikats für die {domain} ist fehlgeschlagen...", "certmanager_certificate_fetching_or_enabling_failed": "Die Aktivierung des neuen Zertifikats für die {domain} ist fehlgeschlagen...",
"certmanager_attempt_to_renew_nonLE_cert": "Das Zertifikat der Domain '{domain}' wurde nicht von Let's Encrypt ausgestellt. Es kann nicht automatisch erneuert werden!", "certmanager_attempt_to_renew_nonLE_cert": "Das Zertifikat der Domain '{domain}' wurde nicht von Let's Encrypt ausgestellt. Es kann nicht automatisch erneuert werden!",
"certmanager_attempt_to_renew_valid_cert": "Das Zertifikat der Domain {domain} läuft nicht in Kürze ab! (Benutze --force um diese Nachricht zu umgehen)", "certmanager_attempt_to_renew_valid_cert": "Das Zertifikat der Domain {domain} läuft nicht in Kürze ab! (Benutze --force um diese Nachricht zu umgehen)",
@ -159,7 +159,7 @@
"certmanager_acme_not_configured_for_domain": "Die ACME-Challenge für {domain} kann momentan nicht ausgeführt werden, weil in Ihrer nginx-Konfiguration das entsprechende Code-Snippet fehlt... Bitte stellen Sie sicher, dass Ihre nginx-Konfiguration mit 'yunohost tools regen-conf nginx --dry-run --with-diff' auf dem neuesten Stand ist.", "certmanager_acme_not_configured_for_domain": "Die ACME-Challenge für {domain} kann momentan nicht ausgeführt werden, weil in Ihrer nginx-Konfiguration das entsprechende Code-Snippet fehlt... Bitte stellen Sie sicher, dass Ihre nginx-Konfiguration mit 'yunohost tools regen-conf nginx --dry-run --with-diff' auf dem neuesten Stand ist.",
"certmanager_unable_to_parse_self_CA_name": "Der Name der Zertifizierungsstelle für selbstsignierte Zertifikate konnte nicht aufgelöst werden (Datei: {file})", "certmanager_unable_to_parse_self_CA_name": "Der Name der Zertifizierungsstelle für selbstsignierte Zertifikate konnte nicht aufgelöst werden (Datei: {file})",
"domain_hostname_failed": "Neuer Hostname wurde nicht gesetzt. Das kann zukünftige Probleme verursachen (es kann auch sein, dass es funktioniert).", "domain_hostname_failed": "Neuer Hostname wurde nicht gesetzt. Das kann zukünftige Probleme verursachen (es kann auch sein, dass es funktioniert).",
"app_already_installed_cant_change_url": "Diese Applikation ist bereits installiert. Die URL kann durch diese Funktion nicht modifiziert werden. Überprüfe ob `app changeurl` verfügbar ist.", "app_already_installed_cant_change_url": "Diese Applikation ist bereits installiert. Die URL kann durch diese Funktion nicht modifiziert werden. Überprüfen Sie ob `app changeurl` verfügbar ist.",
"app_change_url_identical_domains": "Die alte und neue domain/url_path sind identisch: ('{domain} {path}'). Es gibt nichts zu tun.", "app_change_url_identical_domains": "Die alte und neue domain/url_path sind identisch: ('{domain} {path}'). Es gibt nichts zu tun.",
"app_already_up_to_date": "{app} ist bereits aktuell", "app_already_up_to_date": "{app} ist bereits aktuell",
"backup_abstract_method": "Diese Backup-Methode wird noch nicht unterstützt", "backup_abstract_method": "Diese Backup-Methode wird noch nicht unterstützt",
@ -177,14 +177,14 @@
"domain_dns_conf_is_just_a_recommendation": "Dieser Befehl zeigt dir die *empfohlene* Konfiguration. Er konfiguriert *nicht* das DNS für dich. Es liegt in deiner Verantwortung, die DNS-Zone bei deinem DNS-Registrar nach dieser Empfehlung zu konfigurieren.", "domain_dns_conf_is_just_a_recommendation": "Dieser Befehl zeigt dir die *empfohlene* Konfiguration. Er konfiguriert *nicht* das DNS für dich. Es liegt in deiner Verantwortung, die DNS-Zone bei deinem DNS-Registrar nach dieser Empfehlung zu konfigurieren.",
"dpkg_lock_not_available": "Dieser Befehl kann momentan nicht ausgeführt werden, da anscheinend ein anderes Programm die Sperre von dpkg (dem Systempaket-Manager) verwendet", "dpkg_lock_not_available": "Dieser Befehl kann momentan nicht ausgeführt werden, da anscheinend ein anderes Programm die Sperre von dpkg (dem Systempaket-Manager) verwendet",
"confirm_app_install_thirdparty": "Warnung! Diese Applikation ist nicht Teil des App-Katalogs von YunoHost. Die Installation von Drittanbieter Applikationen kann die Integrität und Sicherheit Ihres Systems gefährden. Sie sollten sie NICHT installieren, wenn Sie nicht wissen, was Sie tun. Es wird KEIN SUPPORT geleistet, wenn diese Applikation nicht funktioniert oder Ihr System beschädigt! Wenn Sie dieses Risiko trotzdem eingehen wollen, geben Sie '{answers}' ein", "confirm_app_install_thirdparty": "Warnung! Diese Applikation ist nicht Teil des App-Katalogs von YunoHost. Die Installation von Drittanbieter Applikationen kann die Integrität und Sicherheit Ihres Systems gefährden. Sie sollten sie NICHT installieren, wenn Sie nicht wissen, was Sie tun. Es wird KEIN SUPPORT geleistet, wenn diese Applikation nicht funktioniert oder Ihr System beschädigt! Wenn Sie dieses Risiko trotzdem eingehen wollen, geben Sie '{answers}' ein",
"confirm_app_install_danger": "WARNUNG! Diese Applikation ist noch experimentell (wenn nicht sogar ausdrücklich nicht funktionsfähig)! Du solltest sie wahrscheinlich NICHT installieren, es sei denn, du weißt, was du tust. Es wird keine Unterstützung angeboten, falls diese Applikation nicht funktionieren oder dein System beschädigen sollte... Falls du bereit bist, dieses Risiko einzugehen, tippe '{answers}'", "confirm_app_install_danger": "WARNUNG! Diese Applikation ist noch experimentell (wenn nicht sogar ausdrücklich nicht funktionsfähig)! Sie sollten sie wahrscheinlich NICHT installieren, es sei denn, Sie wissen, was Sie tun. Es wird keine Unterstützung angeboten, falls diese Applikation nicht funktionieren oder Ihr System beschädigen sollte... Falls Sie bereit sind, dieses Risiko einzugehen, tippen Sie '{answers}'",
"confirm_app_install_warning": "Warnung: Diese Applikation funktioniert möglicherweise, ist jedoch nicht gut in YunoHost integriert. Einige Funktionen wie Single-Sign-On und Backup / Restore sind möglicherweise nicht verfügbar. Trotzdem installieren? [{answers}] ", "confirm_app_install_warning": "Warnung: Diese Applikation funktioniert möglicherweise, ist jedoch nicht gut in YunoHost integriert. Einige Funktionen wie Single-Sign-On und Backup / Restore sind möglicherweise nicht verfügbar. Trotzdem installieren? [{answers}] ",
"backup_with_no_restore_script_for_app": "{app} hat kein Wiederherstellungsskript. Das Backup dieser App kann nicht automatisch wiederhergestellt werden.", "backup_with_no_restore_script_for_app": "{app} hat kein Wiederherstellungsskript. Das Backup dieser App kann nicht automatisch wiederhergestellt werden.",
"backup_with_no_backup_script_for_app": "Die App {app} hat kein Sicherungsskript. Ignoriere es.", "backup_with_no_backup_script_for_app": "Die App {app} hat kein Sicherungsskript. Ignoriere es.",
"backup_unable_to_organize_files": "Dateien im Archiv konnten nicht mit der schnellen Methode organisiert werden", "backup_unable_to_organize_files": "Dateien im Archiv konnten nicht mit der schnellen Methode organisiert werden",
"backup_system_part_failed": "Der Systemteil '{part}' konnte nicht gesichert werden", "backup_system_part_failed": "Der Systemteil '{part}' konnte nicht gesichert werden",
"backup_permission": "Sicherungsberechtigung für {app}", "backup_permission": "Sicherungsberechtigung für {app}",
"backup_output_symlink_dir_broken": "Dein Archivverzeichnis '{path}' ist ein fehlerhafter Symlink. Vielleicht hast du vergessen, das Speichermedium, auf das er verweist, neu zu mounten oder einzustecken.", "backup_output_symlink_dir_broken": "Ihr Archivverzeichnis '{path}' ist ein fehlerhafter Symlink. Vielleicht haben Sie vergessen, das Speichermedium, auf das er verweist, neu zu mounten oder einzustecken.",
"backup_mount_archive_for_restore": "Archiv für Wiederherstellung vorbereiten...", "backup_mount_archive_for_restore": "Archiv für Wiederherstellung vorbereiten...",
"backup_method_tar_finished": "Tar-Backup-Archiv erstellt", "backup_method_tar_finished": "Tar-Backup-Archiv erstellt",
"backup_method_custom_finished": "Benutzerdefinierte Sicherungsmethode '{method}' beendet", "backup_method_custom_finished": "Benutzerdefinierte Sicherungsmethode '{method}' beendet",
@ -193,7 +193,7 @@
"backup_custom_backup_error": "Bei der benutzerdefinierten Sicherungsmethode ist beim Arbeitsschritt \"Sicherung\" ein Fehler aufgetreten", "backup_custom_backup_error": "Bei der benutzerdefinierten Sicherungsmethode ist beim Arbeitsschritt \"Sicherung\" ein Fehler aufgetreten",
"backup_csv_creation_failed": "Die zur Wiederherstellung erforderliche CSV-Datei kann nicht erstellt werden", "backup_csv_creation_failed": "Die zur Wiederherstellung erforderliche CSV-Datei kann nicht erstellt werden",
"backup_couldnt_bind": "{src} konnte nicht an {dest} angebunden werden.", "backup_couldnt_bind": "{src} konnte nicht an {dest} angebunden werden.",
"backup_ask_for_copying_if_needed": "Möchtest du die Sicherung mit {size}MB temporär durchführen? (Dieser Weg wird verwendet, da einige Dateien nicht mit einer effizienteren Methode vorbereitet werden konnten.)", "backup_ask_for_copying_if_needed": "Möchten Sie die Datensicherung mit {size}MB temporär durchführen? (Dieser Weg wird verwendet, da einige Dateien nicht mit einer effizienteren Methode vorbereitet werden konnten.)",
"backup_actually_backuping": "Erstellt ein Backup-Archiv aus den gesammelten Dateien...", "backup_actually_backuping": "Erstellt ein Backup-Archiv aus den gesammelten Dateien...",
"ask_new_path": "Neuer Pfad", "ask_new_path": "Neuer Pfad",
"ask_new_domain": "Neue Domain", "ask_new_domain": "Neue Domain",
@ -207,7 +207,7 @@
"app_not_upgraded": "Die App '{failed_app}' konnte nicht aktualisiert werden. Infolgedessen wurden die folgenden App-Upgrades abgebrochen: {apps}", "app_not_upgraded": "Die App '{failed_app}' konnte nicht aktualisiert werden. Infolgedessen wurden die folgenden App-Upgrades abgebrochen: {apps}",
"app_make_default_location_already_used": "Die App \"{app}\" kann nicht als Standard für die Domain \"{domain}\" festgelegt werden. Sie wird bereits von \"{other_app}\" verwendet", "app_make_default_location_already_used": "Die App \"{app}\" kann nicht als Standard für die Domain \"{domain}\" festgelegt werden. Sie wird bereits von \"{other_app}\" verwendet",
"aborting": "Breche ab.", "aborting": "Breche ab.",
"app_action_cannot_be_ran_because_required_services_down": "Diese erforderlichen Dienste sollten zur Durchführung dieser Aktion laufen: {services}. Versuche, sie neu zu starten, um fortzufahren (und möglicherweise zu untersuchen, warum sie nicht verfügbar sind).", "app_action_cannot_be_ran_because_required_services_down": "Diese erforderlichen Dienste sollten zur Durchführung dieser Aktion laufen: {services}. Versuchen Sie, sie neu zu starten, um fortzufahren (und möglicherweise zu untersuchen, warum sie nicht verfügbar sind).",
"already_up_to_date": "Nichts zu tun. Alles ist bereits auf dem neusten Stand.", "already_up_to_date": "Nichts zu tun. Alles ist bereits auf dem neusten Stand.",
"app_action_broke_system": "Diese Aktion scheint diese wichtigen Dienste unterbrochen zu haben: {services}", "app_action_broke_system": "Diese Aktion scheint diese wichtigen Dienste unterbrochen zu haben: {services}",
"apps_already_up_to_date": "Alle Apps sind bereits aktuell", "apps_already_up_to_date": "Alle Apps sind bereits aktuell",
@ -222,18 +222,18 @@
"group_update_failed": "Kann Gruppe '{group}' nicht aktualisieren: {error}", "group_update_failed": "Kann Gruppe '{group}' nicht aktualisieren: {error}",
"log_does_exists": "Es gibt kein Operationsprotokoll mit dem Namen'{log}', verwende 'yunohost log list', um alle verfügbaren Operationsprotokolle anzuzeigen", "log_does_exists": "Es gibt kein Operationsprotokoll mit dem Namen'{log}', verwende 'yunohost log list', um alle verfügbaren Operationsprotokolle anzuzeigen",
"log_operation_unit_unclosed_properly": "Die Operationseinheit wurde nicht richtig geschlossen", "log_operation_unit_unclosed_properly": "Die Operationseinheit wurde nicht richtig geschlossen",
"dpkg_is_broken": "Du kannst das gerade nicht tun, weil dpkg/APT (der Systempaketmanager) in einem defekten Zustand zu sein scheint... Du kannst versuchen, dieses Problem zu lösen, indem du dich über SSH verbindest und `sudo apt install --fix-broken` sowie/oder `sudo dpkg --configure -a` ausführst.", "dpkg_is_broken": "Sie können dies gerade nicht machen, weil dpkg/APT (der Paketmanager des Systems) in einem defekten Zustand zu sein scheint... Sie können versuchen, dieses Problem zu lösen, indem Sie sich über SSH mit dem Server verbinden und `sudo apt install --fix-broken` und/oder `sudo dpkg --configure -a` und/oder `sudo dpkg --audit`ausführen.",
"log_link_to_log": "Vollständiges Log dieser Operation: '<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\">{desc}</a>'", "log_link_to_log": "Vollständiges Log dieser Operation: '<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\">{desc}</a>'",
"log_help_to_get_log": "Um das Protokoll der Operation '{desc}' anzuzeigen, verwende den Befehl 'yunohost log show {name}'", "log_help_to_get_log": "Um das Protokoll der Operation '{desc}' anzuzeigen, verwende den Befehl 'yunohost log show {name}'",
"log_app_remove": "Entferne die Applikation '{}'", "log_app_remove": "Entferne die Applikation '{}'",
"log_app_install": "Installiere die Applikation '{}'", "log_app_install": "Installiere die Applikation '{}'",
"log_app_upgrade": "Upgrade der Applikation '{}'", "log_app_upgrade": "Upgrade der Applikation '{}'",
"good_practices_about_admin_password": "Du bist nun dabei, ein neues Administratorpasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - es ist jedoch empfehlenswert, ein längeres Passwort (z.B. eine Passphrase) und/oder verschiedene Arten von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.", "good_practices_about_admin_password": "Die sind nun dabei, ein neues Administratorpasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - es ist jedoch empfehlenswert, ein längeres Passwort (z.B. eine Passphrase) und/oder verschiedene Arten von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.",
"log_corrupted_md_file": "Die mit Protokollen verknüpfte YAML-Metadatendatei ist beschädigt: '{md_file}\nFehler: {error}''", "log_corrupted_md_file": "Die mit Protokollen verknüpfte YAML-Metadatendatei ist beschädigt: '{md_file}\nFehler: {error}''",
"log_help_to_get_failed_log": "Der Vorgang'{desc}' konnte nicht abgeschlossen werden. Bitte teile das vollständige Protokoll dieser Operation mit dem Befehl 'yunohost log share {name}', um Hilfe zu erhalten", "log_help_to_get_failed_log": "Der Vorgang'{desc}' konnte nicht abgeschlossen werden. Bitte teile das vollständige Protokoll dieser Operation mit dem Befehl 'yunohost log share {name}', um Hilfe zu erhalten",
"backup_no_uncompress_archive_dir": "Dieses unkomprimierte Archivverzeichnis gibt es nicht", "backup_no_uncompress_archive_dir": "Dieses unkomprimierte Archivverzeichnis gibt es nicht",
"log_app_change_url": "Ändere die URL der Applikation '{}'", "log_app_change_url": "Ändere die URL der Applikation '{}'",
"good_practices_about_user_password": "Du bist nun dabei, ein neues Nutzerpasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - es ist jedoch empfehlenswert, ein längeres Passwort (z.B. eine Passphrase) und/oder verschiedene Arten von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.", "good_practices_about_user_password": "Sie sind nun dabei, ein neues Benutzerpasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - es ist jedoch empfehlenswert, ein längeres Passwort (z.B. eine Passphrase) und/oder verschiedene Arten von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.",
"log_link_to_failed_log": "Der Vorgang konnte nicht abgeschlossen werden '{desc}'. Bitte gib das vollständige Protokoll dieser Operation mit <a href=\"#/tools/logs/{name}\">Klicken Sie hier</a> an, um Hilfe zu erhalten", "log_link_to_failed_log": "Der Vorgang konnte nicht abgeschlossen werden '{desc}'. Bitte gib das vollständige Protokoll dieser Operation mit <a href=\"#/tools/logs/{name}\">Klicken Sie hier</a> an, um Hilfe zu erhalten",
"backup_cant_mount_uncompress_archive": "Das unkomprimierte Archiv konnte nicht als schreibgeschützt gemountet werden", "backup_cant_mount_uncompress_archive": "Das unkomprimierte Archiv konnte nicht als schreibgeschützt gemountet werden",
"backup_csv_addition_failed": "Es konnten keine Dateien zur Sicherung in die CSV-Datei hinzugefügt werden", "backup_csv_addition_failed": "Es konnten keine Dateien zur Sicherung in die CSV-Datei hinzugefügt werden",
@ -248,7 +248,7 @@
"diagnosis_basesystem_kernel": "Server läuft unter Linux-Kernel {kernel_version}", "diagnosis_basesystem_kernel": "Server läuft unter Linux-Kernel {kernel_version}",
"diagnosis_basesystem_ynh_single_version": "{package} Version: {version} ({repo})", "diagnosis_basesystem_ynh_single_version": "{package} Version: {version} ({repo})",
"diagnosis_basesystem_ynh_main_version": "Server läuft YunoHost {main_version} ({repo})", "diagnosis_basesystem_ynh_main_version": "Server läuft YunoHost {main_version} ({repo})",
"diagnosis_basesystem_ynh_inconsistent_versions": "Du verwendest inkonsistente Versionen der YunoHost-Pakete... wahrscheinlich wegen eines fehlgeschlagenen oder teilweisen Upgrades.", "diagnosis_basesystem_ynh_inconsistent_versions": "Sie verwenden inkonsistente Versionen der YunoHost-Pakete... wahrscheinlich wegen eines fehlgeschlagenen oder teilweisen Upgrades.",
"apps_catalog_init_success": "App-Katalogsystem initialisiert!", "apps_catalog_init_success": "App-Katalogsystem initialisiert!",
"apps_catalog_updating": "Aktualisierung des Applikationskatalogs...", "apps_catalog_updating": "Aktualisierung des Applikationskatalogs...",
"apps_catalog_failed_to_download": "Der {apps_catalog} App-Katalog kann nicht heruntergeladen werden: {error}", "apps_catalog_failed_to_download": "Der {apps_catalog} App-Katalog kann nicht heruntergeladen werden: {error}",
@ -264,25 +264,25 @@
"diagnosis_ip_no_ipv6": "Der Server verfügt nicht über eine funktionierende IPv6-Adresse.", "diagnosis_ip_no_ipv6": "Der Server verfügt nicht über eine funktionierende IPv6-Adresse.",
"diagnosis_ip_not_connected_at_all": "Der Server scheint überhaupt nicht mit dem Internet verbunden zu sein!?", "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_failed_for_category": "Diagnose fehlgeschlagen für die Kategorie '{category}': {error}",
"diagnosis_cache_still_valid": "(Cache noch gültig für {category} Diagnose. Es wird keine neue Diagnose durchgeführt!)", "diagnosis_cache_still_valid": "(Der Cache für die {category} Diagnose ist noch gültig. 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_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_found_errors_and_warnings": "{errors} erhebliche(s) Problem(e) (und {warnings} Warnung(en)) in Verbindung mit {category} gefunden!",
"diagnosis_ip_broken_dnsresolution": "Domänennamen-Auflösung scheint aus einem bestimmten Grund nicht zu funktionieren... Blockiert vielleicht eine Firewall die DNS-Anfragen?", "diagnosis_ip_broken_dnsresolution": "Domänennamen-Auflösung scheint aus einem bestimmten Grund nicht zu funktionieren... Blockiert vielleicht eine Firewall die DNS-Anfragen?",
"diagnosis_ip_broken_resolvconf": "Domänen-Namensauflösung scheint nicht zu funktionieren, was daran liegen könnte, dass in <code>/etc/resolv.conf</code> kein Eintrag auf <code>127.0.0.1</code> zeigt.", "diagnosis_ip_broken_resolvconf": "Domänen-Namensauflösung scheint nicht zu funktionieren, was daran liegen könnte, dass in <code>/etc/resolv.conf</code> kein Eintrag auf <code>127.0.0.1</code> zeigt.",
"diagnosis_ip_weird_resolvconf_details": "Die Datei <code>/etc/resolv.conf</code> muss ein Symlink auf <code>/etc/resolvconf/run/resolv.conf</code> sein, welcher auf <code>127.0.0.1</code> (dnsmasq) zeigt. Falls du die DNS-Resolver manuell konfigurieren möchtest, bearbeite bitte <code>/etc/resolv.dnsmasq.conf</code>.", "diagnosis_ip_weird_resolvconf_details": "Die Datei <code>/etc/resolv.conf</code> muss ein Symlink auf <code>/etc/resolvconf/run/resolv.conf</code> sein, welcher auf <code>127.0.0.1</code> (dnsmasq) zeigt. Falls du die DNS-Resolver manuell konfigurieren möchtest, bearbeite bitte <code>/etc/resolv.dnsmasq.conf</code>.",
"diagnosis_dns_good_conf": "DNS Einträge korrekt konfiguriert für die Domäne {domain} (Kategorie {category})", "diagnosis_dns_good_conf": "DNS Einträge korrekt konfiguriert für die Domäne {domain} (Kategorie {category})",
"diagnosis_ignored_issues": "(+ {nb_ignored} ignorierte(s) Problem(e))", "diagnosis_ignored_issues": "(+ {nb_ignored} ignorierte(s) Problem(e))",
"diagnosis_basesystem_hardware": "Server Hardware Architektur ist {virt} {arch}", "diagnosis_basesystem_hardware": "Server Hardware Architektur ist {virt} {arch}",
"diagnosis_found_errors": "Habe {errors} erhebliche(s) Problem(e) in Verbindung mit {category} gefunden!", "diagnosis_found_errors": "{errors} erhebliche(s) Problem(e) in Verbindung mit {category} gefunden!",
"diagnosis_found_warnings": "Habe {warnings} Ding(e) gefunden, die verbessert werden könnten für {category}.", "diagnosis_found_warnings": "Habe {warnings} Ding(e) gefunden, die verbessert werden könnten für {category}.",
"diagnosis_ip_dnsresolution_working": "Domänen-Namens-Auflösung funktioniert!", "diagnosis_ip_dnsresolution_working": "Domänen-Namens-Auflösung funktioniert!",
"diagnosis_ip_weird_resolvconf": "DNS Auflösung scheint zu funktionieren, aber sei vorsichtig wenn du deine eigene <code>/etc/resolv.conf</code> verwendest.", "diagnosis_ip_weird_resolvconf": "DNS Auflösung scheint zu funktionieren, aber sei vorsichtig wenn du deine eigene <code>/etc/resolv.conf</code> verwendest.",
"diagnosis_display_tip": "Um die gefundenen Probleme zu sehen, kannst du zum Diagnose-Bereich des webadmin gehen, oder 'yunohost diagnosis show --issues --human-readable' in der Kommandozeile ausführen.", "diagnosis_display_tip": "Damit Sie die gefundenen Probleme anschauen können, gehen Sie zum Diagnose-Bereich des Admin-Panels, oder führen Sie 'yunohost diagnosis show --issues --human-readable' in der Kommandozeile aus.",
"backup_archive_corrupted": "Das Backup-Archiv '{archive}' scheint beschädigt: {error}", "backup_archive_corrupted": "Das Backup-Archiv '{archive}' scheint beschädigt: {error}",
"backup_archive_cant_retrieve_info_json": "Die Informationen für das Archiv '{archive}' konnten nicht geladen werden... Die Datei info.json wurde nicht gefunden (oder ist kein gültiges json).", "backup_archive_cant_retrieve_info_json": "Die Informationen für das Archiv '{archive}' konnten nicht geladen werden... Die Datei info.json wurde nicht gefunden (oder ist kein gültiges json).",
"app_packaging_format_not_supported": "Diese App kann nicht installiert werden da das Paketformat nicht von der YunoHost-Version unterstützt wird. Am besten solltest du dein System aktualisieren.", "app_packaging_format_not_supported": "Diese App kann nicht installiert werden da das Paketformat nicht von der YunoHost-Version unterstützt wird. Am besten sollten Sie Ihr System aktualisieren.",
"certmanager_domain_not_diagnosed_yet": "Für die Domäne {domain} gibt es noch keine Diagnose-Resultate. Bitte wiederholen Sie die Diagnose für die Kategorien 'DNS-Einträge' und 'Web' im Diagnose-Bereich um zu überprüfen ob die Domäne für Let's Encrypt bereit ist. (Wenn Sie wissen was Sie tun, können Sie --no-checks benutzen, um diese Überprüfung zu überspringen.)", "certmanager_domain_not_diagnosed_yet": "Für die Domäne {domain} gibt es noch keine Diagnose-Resultate. Bitte wiederholen Sie die Diagnose für die Kategorien 'DNS-Einträge' und 'Web' im Diagnose-Bereich um zu überprüfen ob die Domäne für Let's Encrypt bereit ist. (Wenn Sie wissen was Sie tun, können Sie --no-checks benutzen, um diese Überprüfung zu überspringen.)",
"mail_unavailable": "Diese E-Mail Adresse ist reserviert und wird dem ersten Konto automatisch zugewiesen", "mail_unavailable": "Diese E-Mail-Adresse ist für die Administratoren-Gruppe reserviert",
"diagnosis_services_conf_broken": "Die Konfiguration für den Dienst {service} ist fehlerhaft!", "diagnosis_services_conf_broken": "Die Konfiguration für den Dienst {service} ist fehlerhaft!",
"diagnosis_services_running": "Dienst {service} läuft!", "diagnosis_services_running": "Dienst {service} läuft!",
"diagnosis_domain_expires_in": "{domain} läuft in {days} Tagen ab.", "diagnosis_domain_expires_in": "{domain} läuft in {days} Tagen ab.",
@ -290,31 +290,31 @@
"diagnosis_domain_expiration_success": "Deine Domänen sind registriert und werden in nächster Zeit nicht ablaufen.", "diagnosis_domain_expiration_success": "Deine 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_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_domain_expiration_not_found": "Das Ablaufdatum einiger Domains kann nicht überprüft werden",
"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_try_dyndns_update_force": "Die DNS-Konfiguration dieser Domäne sollte automatisch von YunoHost verwaltet werden. Andernfalls können Sie mittels <cmd>yunohost dyndns update --force</cmd> ein Update erzwingen.",
"diagnosis_dns_point_to_doc": "Bitte schauen Sie in der Dokumentation unter <a href='https://yunohost.org/dns_config'>https://yunohost.org/dns_config</a> nach, wenn Sie Hilfe bei der Konfiguration der DNS-Einträge benötigen.", "diagnosis_dns_point_to_doc": "Bitte schauen Sie in der Dokumentation unter <a href='https://yunohost.org/dns_config'>https://yunohost.org/dns_config</a> nach, wenn Sie Hilfe bei der Konfiguration der DNS-Einträge benötigen.",
"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_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 solltest du einen DNS-Eintrag mit den folgenden Informationen hinzufügen.<br>Typ: <code>{type}</code><br>Name: <code>{name}</code><br>Wert: <code>{value}</code>", "diagnosis_dns_missing_record": "Gemäss 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>",
"diagnosis_dns_bad_conf": "Einige DNS-Einträge für die Domäne {domain} fehlen oder sind nicht korrekt (Kategorie {category})", "diagnosis_dns_bad_conf": "Einige DNS-Einträge für die Domäne {domain} fehlen oder sind nicht korrekt (Kategorie {category})",
"diagnosis_ip_local": "Lokale IP: <code>{local}</code>", "diagnosis_ip_local": "Lokale IP: <code>{local}</code>",
"diagnosis_ip_global": "Globale IP: <code>{global}</code>", "diagnosis_ip_global": "Globale IP: <code>{global}</code>",
"diagnosis_ip_no_ipv6_tip": "Ein funktionierendes IPv6 ist für den Betrieb Ihres Servers nicht zwingend erforderlich, aber es ist besser für das Funktionieren des Internets als Ganzes. IPv6 sollte normalerweise automatisch vom System oder Ihrem Provider konfiguriert werden, wenn es verfügbar ist. Andernfalls müssen Sie möglicherweise einige Dinge manuell konfigurieren, wie in der Dokumentation hier beschrieben: <a href='https://yunohost.org/#/ipv6'>https://yunohost.org/#/ipv6</a>. Wenn Sie IPv6 nicht aktivieren können oder wenn es Ihnen zu technisch erscheint, können Sie diese Warnung auch getrost ignorieren.", "diagnosis_ip_no_ipv6_tip": "Ein funktionierendes IPv6 ist für den Betrieb Ihres Servers nicht zwingend erforderlich, aber es ist besser für das Funktionieren des Internets als Ganzes. IPv6 sollte normalerweise automatisch vom System oder Ihrem Provider konfiguriert werden, wenn es verfügbar ist. Andernfalls müssen Sie möglicherweise einige Dinge manuell konfigurieren, wie in der Dokumentation hier beschrieben: <a href='https://yunohost.org/#/ipv6'>https://yunohost.org/#/ipv6</a>. Wenn Sie IPv6 nicht aktivieren können oder wenn es Ihnen zu technisch erscheint, können Sie diese Warnung auch getrost ignorieren.",
"diagnosis_services_bad_status_tip": "Du kannst versuchen, <a href='#/services/{service}'>den Dienst neu zu starten</a>, und wenn das nicht funktioniert, schaue dir <a href='#/services/{service}'>die (Dienst-)Logs in der Verwaltung</a> an (In der Kommandozeile kannst du dies mit <cmd>yunohost service restart {service}</cmd> und <cmd>yunohost service log {service}</cmd> tun).", "diagnosis_services_bad_status_tip": "Du kannst versuchen, <a href='#/services/{service}'>den Dienst neu zu starten</a>, und wenn das nicht funktioniert, schaue dir <a href='#/services/{service}'>die (Dienst-)Logs in der Verwaltung</a> an (In der Kommandozeile kannst du dies mit <cmd>yunohost service restart {service}</cmd> und <cmd>yunohost service log {service}</cmd> tun).",
"diagnosis_services_bad_status": "Der Dienst {service} ist {status} :(", "diagnosis_services_bad_status": "Der Dienst {service} ist {status} :(",
"diagnosis_diskusage_verylow": "Der Speicher <code>{mountpoint}</code> (auf Gerät <code>{device}</code>) hat nur noch {free} ({free_percent}%) freien Speicherplatz (von ingesamt {total}). Du solltest ernsthaft in Betracht ziehen, etwas Seicherplatz frei zu machen!", "diagnosis_diskusage_verylow": "Der Speicher <code>{mountpoint}</code> (auf Gerät <code>{device}</code>) hat nur noch {free} ({free_percent}%) freien Speicherplatz (von ingesamt {total}). Sie sollten ernsthaft in Betracht ziehen, etwas Seicherplatz frei zu machen!",
"diagnosis_http_ok": "Die Domäne {domain} ist über HTTP von außerhalb des lokalen Netzwerks erreichbar.", "diagnosis_http_ok": "Die Domäne {domain} ist über HTTP von außerhalb des lokalen Netzwerks erreichbar.",
"diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Einige Hosting-Anbieter werden es Ihnen nicht gestatten, den ausgehenden Port 25 zu öffnen, weil Ihnen die Netzneutralität nichts bedeutet.<br>- Einige davon bieten als Alternative an, <a href='https://yunohost.org/#/email_configure_relay'>ein Mailserver-Relay zu verwenden</a>, was jedoch bedeutet, dass das Relay Ihren E-Mail-Verkehr ausspionieren kann.<br>- Eine Alternative, welche die Privatsphäre berücksichtigt, wäre die Verwendung eines VPN *mit einer öffentlichen dedizierten IP* um solche Einschränkungen zu umgehen. Schauen Sie unter <a href='https://yunohost.org/#/vpn_advantage'>https://yunohost.org/#/vpn_advantage</a> nach.<br>- Sie können auch in Betracht ziehen, zu einem <a href='https://yunohost.org/#/isp'>netzneutralitätfreundlicheren Anbieter</a> zu wechseln", "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Einige Hosting-Anbieter werden es Ihnen nicht gestatten, den ausgehenden Port 25 zu öffnen, weil Ihnen die Netzneutralität nichts bedeutet.<br>- Einige davon bieten als Alternative an, <a href='https://yunohost.org/#/email_configure_relay'>ein Mailserver-Relay zu verwenden</a>, was jedoch bedeutet, dass das Relay Ihren E-Mail-Verkehr ausspionieren kann.<br>- Eine Alternative, welche die Privatsphäre berücksichtigt, wäre die Verwendung eines VPN *mit einer öffentlichen dedizierten IP* um solche Einschränkungen zu umgehen. Schauen Sie unter <a href='https://yunohost.org/#/vpn_advantage'>https://yunohost.org/#/vpn_advantage</a> nach.<br>- Sie können auch in Betracht ziehen, zu einem <a href='https://yunohost.org/#/isp'>netzneutralitätfreundlicheren Anbieter</a> zu wechseln",
"diagnosis_http_timeout": "Wartezeit wurde beim Versuch überschritten, von Aussen eine Verbindung zu Ihrem Server aufzubauen. Er scheint nicht erreichbar zu sein.<br>1. Die häufigste Ursache für dieses Problem ist, dass die Ports 80 und 433 <a href='https://yunohost.org/isp_box_config'>nicht richtig zu Ihrem Server weitergeleitet werden</a>.<br>2. Sie sollten zudem sicherstellen, dass der Dienst nginx läuft.<br>3. In komplexeren Umgebungen: Stellen Sie sicher, dass keine Firewall oder Reverse-Proxy stört .", "diagnosis_http_timeout": "Wartezeit wurde beim Versuch überschritten, von Aussen eine Verbindung zu Ihrem Server aufzubauen. Er scheint nicht erreichbar zu sein.<br>1. Die häufigste Ursache für dieses Problem ist, dass die Ports 80 und 433 <a href='https://yunohost.org/isp_box_config'>nicht richtig zu Ihrem Server weitergeleitet werden</a>.<br>2. Sie sollten zudem sicherstellen, dass der Dienst nginx läuft.<br>3. In komplexeren Umgebungen: Stellen Sie sicher, dass keine Firewall oder Reverse-Proxy stört .",
"service_reloaded_or_restarted": "Der Dienst '{service}' wurde erfolgreich neu geladen oder gestartet", "service_reloaded_or_restarted": "Der Dienst '{service}' wurde erfolgreich neu geladen oder gestartet",
"service_restarted": "Der Dienst '{service}' wurde neu gestartet", "service_restarted": "Der Dienst '{service}' wurde neu gestartet",
"certmanager_warning_subdomain_dns_record": "Die Subdomäne \"{subdomain}\" löst nicht zur gleichen IP Adresse auf wie \"{domain}\". Einige Funktionen sind nicht verfügbar bis du dies behebst und die Zertifikate neu erzeugst.", "certmanager_warning_subdomain_dns_record": "Die Subdomäne \"{subdomain}\" löst nicht zur gleichen IP Adresse auf wie \"{domain}\". Einige Funktionen werden nicht verfügbar sein bis Sie dies behoben und die Zertifikate neu erzeugt haben.",
"diagnosis_ports_ok": "Port {port} ist von Aussen erreichbar.", "diagnosis_ports_ok": "Port {port} ist von Aussen erreichbar.",
"diagnosis_ram_verylow": "Das System hat nur {available} ({available_percent}%) RAM zur Verfügung! (von insgesamt {total})", "diagnosis_ram_verylow": "Das System hat nur {available} ({available_percent}%) RAM zur Verfügung! (von insgesamt {total})",
"diagnosis_mail_outgoing_port_25_blocked_details": "Sie sollten zuerst versuchen, den ausgehenden Port 25 in Ihrer Router-Konfigurationsoberfläche oder in der Konfigurationsoberfläche Ihres Hosting-Anbieters zu öffnen. (Bei einigen Hosting-Anbietern kann es sein, dass man von Ihnen verlangt, dass Sie dafür ein Support-Ticket erstellen).", "diagnosis_mail_outgoing_port_25_blocked_details": "Sie sollten zuerst versuchen, den ausgehenden Port 25 in Ihrer Router-Konfigurationsoberfläche oder in der Konfigurationsoberfläche Ihres Hosting-Anbieters zu öffnen. (Bei einigen Hosting-Anbietern kann es sein, dass man von Ihnen verlangt, dass Sie dafür ein Support-Ticket erstellen).",
"diagnosis_mail_ehlo_ok": "Der SMTP-Server ist von von außen erreichbar und darum auch in der Lage E-Mails zu empfangen!", "diagnosis_mail_ehlo_ok": "Der SMTP-Server ist von Aussen erreichbar und darum auch in der Lage E-Mails zu empfangen!",
"diagnosis_mail_ehlo_bad_answer": "Ein nicht-SMTP-Dienst antwortete auf Port 25 per IPv{ipversion}", "diagnosis_mail_ehlo_bad_answer": "Ein nicht-SMTP-Dienst antwortete auf Port 25 per IPv{ipversion}",
"diagnosis_swap_notsomuch": "Das System hat nur {total} Swap. Du solltest dir überlegen mindestens {recommended} an Swap einzurichten, um Situationen zu verhindern, in welchen der RAM des Systems knapp wird.", "diagnosis_swap_notsomuch": "Das System hat nur {total} Swap. Du solltest dir überlegen mindestens {recommended} an Swap einzurichten, um Situationen zu verhindern, in welchen der RAM des Systems knapp wird.",
"diagnosis_swap_ok": "Das System hat {total} Swap!", "diagnosis_swap_ok": "Das System hat {total} Swap!",
"diagnosis_swap_tip": "Bitte beachte, dass das Betreiben der Swap-Partition auf einer SD-Karte oder SSD die Lebenszeit dieser drastisch reduziert.", "diagnosis_swap_tip": "Bitte wahren Sie Vorsicht und Aufmerksamkeit, dass das Betreiben der Swap-Partition auf einer SD-Karte oder einer SSD die Lebenszeit dieses Geräts drastisch reduzieren kann.",
"diagnosis_mail_outgoing_port_25_ok": "Der SMTP-Server ist in der Lage E-Mails zu versenden (der ausgehende Port 25 ist nicht blockiert).", "diagnosis_mail_outgoing_port_25_ok": "Der SMTP-Server ist in der Lage E-Mails zu versenden (der ausgehende Port 25 ist nicht blockiert).",
"diagnosis_mail_outgoing_port_25_blocked": "Der SMTP-Server kann keine E-Mails an andere Server senden, weil der ausgehende Port 25 per IPv{ipversion} blockiert ist. Du kannst versuchen, diesen in der Konfigurations-Oberfläche deines Internet-Anbieters (oder Hosters) zu öffnen.", "diagnosis_mail_outgoing_port_25_blocked": "Der SMTP-Server kann keine E-Mails an andere Server senden, weil der ausgehende Port 25 per IPv{ipversion} blockiert ist. Du kannst versuchen, diesen in der Konfigurations-Oberfläche deines Internet-Anbieters (oder Hosters) zu öffnen.",
"diagnosis_mail_ehlo_unreachable": "Der SMTP-Server ist von außen nicht erreichbar per IPv{ipversion}. Er wird nicht in der Lage sein E-Mails zu empfangen.", "diagnosis_mail_ehlo_unreachable": "Der SMTP-Server ist von außen nicht erreichbar per IPv{ipversion}. Er wird nicht in der Lage sein E-Mails zu empfangen.",
@ -352,7 +352,7 @@
"diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Aktueller Reverse-DNS-Eintrag: <code>{rdns_domain}</code><br>Erwarteter Wert: <code>{ehlo_domain}</code>", "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Aktueller Reverse-DNS-Eintrag: <code>{rdns_domain}</code><br>Erwarteter Wert: <code>{ehlo_domain}</code>",
"diagnosis_mail_fcrdns_different_from_ehlo_domain": "Reverse-DNS-Eintrag ist nicht korrekt konfiguriert für IPv{ipversion}. Einige E-Mails könnten eventuell nicht zugestellt oder als Spam markiert werden.", "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Reverse-DNS-Eintrag ist nicht korrekt konfiguriert für IPv{ipversion}. Einige E-Mails könnten eventuell nicht zugestellt oder als Spam markiert werden.",
"diagnosis_mail_fcrdns_nok_alternatives_6": "Einige Provider werden es Ihnen vermutlich nicht erlauben, den Reverse-DNS-Eintrag zu konfigurieren (oder vielleicht ist diese Funktion beschädigt...). Falls Sie Ihren Reverse-DNS-Eintrag für IPv4 korrekt konfiguriert haben, können Sie versuchen, die Verwendung von IPv6 für das Versenden von E-Mails auszuschalten, indem Sie den Befehl <cmd>yunohost settings set smtp.allow_ipv6 -v off</cmd> ausführen. Bemerkung: Die Folge dieser letzten Lösung ist, dass Sie mit Servern, welche nur über IPv6 verfügen, keine E-Mails mehr versenden oder empfangen können.", "diagnosis_mail_fcrdns_nok_alternatives_6": "Einige Provider werden es Ihnen vermutlich nicht erlauben, den Reverse-DNS-Eintrag zu konfigurieren (oder vielleicht ist diese Funktion beschädigt...). Falls Sie Ihren Reverse-DNS-Eintrag für IPv4 korrekt konfiguriert haben, können Sie versuchen, die Verwendung von IPv6 für das Versenden von E-Mails auszuschalten, indem Sie den Befehl <cmd>yunohost settings set smtp.allow_ipv6 -v off</cmd> ausführen. Bemerkung: Die Folge dieser letzten Lösung ist, dass Sie mit Servern, welche nur über IPv6 verfügen, keine E-Mails mehr versenden oder empfangen können.",
"diagnosis_mail_fcrdns_nok_alternatives_4": "Einige Anbieter werden es nicht zulassen, den Reverse-DNS zu konfigurieren (oder diese Funktion ist defekt...). Falls du deswegen auf Probleme stoßen solltest, ziehe folgende Lösungen in Betracht:<br> - Manche ISPs stellen als Alternative <a href='https://yunohost.org/#/email_configure_relay'>die Benutzung eines Mail-Server-Relays</a> zur Verfügung, was jedoch mit sich zieht, dass das Relay Ihren E-Mail-Verkehr ausspionieren kann. <br> - Eine privatsphärenfreundlichere Alternative ist die Benutzung eines VPN *mit einer dedizierten öffentlichen IP* um Einschränkungen dieser Art zu umgehen. Schaue hier nach <a href='https://yunohost.org/#/vpn_advantage'>https://yunohost.org/#/vpn_advantage</a><br>- Schließlich ist es auch möglich <a href='https://yunohost.org/#/isp'>zu einem anderen Anbieter zu wechseln</a>", "diagnosis_mail_fcrdns_nok_alternatives_4": "Einige Provider werden Ihnen nicht erlauben, den Reverse-DNS zu konfigurieren (oder deren Funktionalität ist defekt...). Falls Sie deswegen auf Probleme stossen sollten, ziehen Sie folgende Lösungen in Betracht:<br> - Manche ISPs stellen als Alternative <a href='https://yunohost.org/#/email_configure_relay'>die Benutzung eines Mail-Server-Relays</a> zur Verfügung, was jedoch mit sich zieht, dass das Relay Ihren E-Mail-Verkehr ausspionieren könnte. <br> - Eine privatsphärenfreundlichere Alternative ist die Benutzung eines VPN *mit einer dedizierten öffentlichen IP* um Einschränkungen dieser Art zu umgehen. Schauen Sie hier nach <a href='https://yunohost.org/#/vpn_advantage'>https://yunohost.org/#/vpn_advantage</a><br>- Schließlich ist es auch möglich, <a href='https://yunohost.org/#/isp'>zu einem anderen Provider zu wechseln</a>",
"diagnosis_mail_queue_unavailable_details": "Fehler: {error}", "diagnosis_mail_queue_unavailable_details": "Fehler: {error}",
"diagnosis_mail_queue_unavailable": "Die Anzahl der anstehenden Nachrichten in der Warteschlange kann nicht abgefragt werden", "diagnosis_mail_queue_unavailable": "Die Anzahl der anstehenden Nachrichten in der Warteschlange kann nicht abgefragt werden",
"diagnosis_mail_queue_ok": "{nb_pending} anstehende E-Mails in der Warteschlange", "diagnosis_mail_queue_ok": "{nb_pending} anstehende E-Mails in der Warteschlange",
@ -364,10 +364,10 @@
"diagnosis_http_connection_error": "Verbindungsfehler: konnte nicht zur angeforderten Domäne verbinden, es ist sehr wahrscheinlich, dass sie nicht erreichbat ist.", "diagnosis_http_connection_error": "Verbindungsfehler: konnte nicht zur angeforderten Domäne verbinden, es ist sehr wahrscheinlich, dass sie nicht erreichbat ist.",
"diagnosis_http_could_not_diagnose_details": "Fehler: {error}", "diagnosis_http_could_not_diagnose_details": "Fehler: {error}",
"diagnosis_http_could_not_diagnose": "Konnte nicht diagnostizieren, ob die Domäne von aussen per IPv{ipversion} erreichbar ist.", "diagnosis_http_could_not_diagnose": "Konnte nicht diagnostizieren, ob die Domäne von aussen per IPv{ipversion} erreichbar ist.",
"diagnosis_ports_partially_unreachable": "Port {port} ist von aussen per IPv{failed} nicht erreichbar.", "diagnosis_ports_partially_unreachable": "Port {port} ist von Aussen her per IPv{failed} nicht erreichbar.",
"diagnosis_ports_unreachable": "Port {port} ist von aussen nicht erreichbar.", "diagnosis_ports_unreachable": "Port {port} ist von Aussen her nicht erreichbar.",
"diagnosis_ports_could_not_diagnose_details": "Fehler: {error}", "diagnosis_ports_could_not_diagnose_details": "Fehler: {error}",
"diagnosis_security_vulnerable_to_meltdown_details": "Um dieses Problem zu beheben, solltest du dein System upgraden und neustarten um den neuen Linux-Kernel zu laden (oder deinen Server-Anbieter kontaktieren, falls das nicht funktionieren sollte). Besuche https://meltdownattack.com/ für weitere Informationen.", "diagnosis_security_vulnerable_to_meltdown_details": "Um dieses Problem zu beheben, solltest Sie Ihr System upgraden und neustarten um den neuen Linux-Kernel zu laden (oder Ihren Server-Anbieter kontaktieren, falls das nicht funktionieren sollte). Besuchen Sie https://meltdownattack.com/ für weitere Informationen.",
"diagnosis_ports_could_not_diagnose": "Konnte nicht diagnostizieren, ob die Ports von aussen per IPv{ipversion} erreichbar sind.", "diagnosis_ports_could_not_diagnose": "Konnte nicht diagnostizieren, ob die Ports von aussen per IPv{ipversion} erreichbar sind.",
"diagnosis_description_regenconf": "Systemkonfiguration", "diagnosis_description_regenconf": "Systemkonfiguration",
"diagnosis_description_mail": "E-Mail", "diagnosis_description_mail": "E-Mail",
@ -377,9 +377,9 @@
"diagnosis_description_dnsrecords": "DNS-Einträge", "diagnosis_description_dnsrecords": "DNS-Einträge",
"diagnosis_description_ip": "Internetkonnektivität", "diagnosis_description_ip": "Internetkonnektivität",
"diagnosis_description_basesystem": "Grundsystem", "diagnosis_description_basesystem": "Grundsystem",
"diagnosis_security_vulnerable_to_meltdown": "Es scheint, als ob du durch die kritische Meltdown-Sicherheitslücke verwundbar bist", "diagnosis_security_vulnerable_to_meltdown": "Es scheint als ob Sie durch die kritische Meltdown-Verwundbarkeit verwundbar sind",
"diagnosis_regenconf_manually_modified": "Die Konfigurationsdatei <code>{file}</code> scheint manuell verändert worden zu sein.", "diagnosis_regenconf_manually_modified": "Die Konfigurationsdatei <code>{file}</code> scheint manuell verändert worden zu sein.",
"diagnosis_regenconf_allgood": "Alle Konfigurationsdateien stimmen mit der empfohlenen Konfiguration überein!", "diagnosis_regenconf_allgood": "Alle Konfigurationsdateien sind in Übereinstimmung mit der empfohlenen Konfiguration!",
"diagnosis_package_installed_from_sury": "Einige System-Pakete sollten gedowngradet werden", "diagnosis_package_installed_from_sury": "Einige System-Pakete sollten gedowngradet werden",
"diagnosis_ports_forwarding_tip": "Um dieses Problem zu beheben, musst du höchstwahrscheinlich die Port-Weiterleitung auf deinem Internet-Router einrichten wie in <a href='https://yunohost.org/isp_box_config'>https://yunohost.org/isp_box_config</a> beschrieben", "diagnosis_ports_forwarding_tip": "Um dieses Problem zu beheben, musst du höchstwahrscheinlich die Port-Weiterleitung auf deinem Internet-Router einrichten wie in <a href='https://yunohost.org/isp_box_config'>https://yunohost.org/isp_box_config</a> beschrieben",
"diagnosis_regenconf_manually_modified_details": "Das ist wahrscheinlich OK wenn du weißt, was du tust! YunoHost wird in Zukunft diese Datei nicht mehr automatisch updaten... Aber sei bitte vorsichtig, da die zukünftigen Upgrades von YunoHost wichtige empfohlene Änderungen enthalten könnten. Wenn du möchtest, kannst du die Unterschiede mit <cmd>yunohost tools regen-conf {category} --dry-run --with-diff</cmd> inspizieren und mit <cmd>yunohost tools regen-conf {category} --force</cmd> auf das Zurücksetzen die empfohlene Konfiguration erzwingen", "diagnosis_regenconf_manually_modified_details": "Das ist wahrscheinlich OK wenn du weißt, was du tust! YunoHost wird in Zukunft diese Datei nicht mehr automatisch updaten... Aber sei bitte vorsichtig, da die zukünftigen Upgrades von YunoHost wichtige empfohlene Änderungen enthalten könnten. Wenn du möchtest, kannst du die Unterschiede mit <cmd>yunohost tools regen-conf {category} --dry-run --with-diff</cmd> inspizieren und mit <cmd>yunohost tools regen-conf {category} --force</cmd> auf das Zurücksetzen die empfohlene Konfiguration erzwingen",
@ -389,17 +389,17 @@
"diagnosis_ports_needed_by": "Diesen Port zu öffnen ist nötig, um die Funktionalität des Typs {category} (service {service}) zu gewährleisten", "diagnosis_ports_needed_by": "Diesen Port zu öffnen ist nötig, um die Funktionalität des Typs {category} (service {service}) zu gewährleisten",
"diagnosis_mail_queue_too_big": "Zu viele anstehende Nachrichten in der Warteschlange ({nb_pending} emails)", "diagnosis_mail_queue_too_big": "Zu viele anstehende Nachrichten in der Warteschlange ({nb_pending} emails)",
"diagnosis_package_installed_from_sury_details": "Einige Pakete wurden versehentlich von einem Drittanbieter-Repository namens Sury installiert. Das YunoHost-Team hat die Strategie für den Umgang mit diesen Paketen verbessert, aber es ist zu erwarten, dass einige Setups, die PHP7.3-Anwendungen installiert haben, während sie noch auf Stretch waren, einige verbleibende Inkonsistenzen aufweisen. Um diese Situation zu beheben, sollten Sie versuchen, den folgenden Befehl auszuführen: <cmd>{cmd_to_fix}</cmd>", "diagnosis_package_installed_from_sury_details": "Einige Pakete wurden versehentlich von einem Drittanbieter-Repository namens Sury installiert. Das YunoHost-Team hat die Strategie für den Umgang mit diesen Paketen verbessert, aber es ist zu erwarten, dass einige Setups, die PHP7.3-Anwendungen installiert haben, während sie noch auf Stretch waren, einige verbleibende Inkonsistenzen aufweisen. Um diese Situation zu beheben, sollten Sie versuchen, den folgenden Befehl auszuführen: <cmd>{cmd_to_fix}</cmd>",
"domain_cannot_add_xmpp_upload": "Eine hinzugefügte Domain darf nicht mit 'xmpp-upload.' beginnen. Dieser Name ist für das XMPP-Upload-Feature von YunoHost reserviert.", "domain_cannot_add_xmpp_upload": "Sie können keine Domänen hinzufügen, welche mit 'xmpp-upload.' beginnen. Diese Art von Namen ist für die in YunoHost integrierte XMPP-Upload-Feature reserviert.",
"group_cannot_be_deleted": "Die Gruppe {group} kann nicht manuell entfernt werden.", "group_cannot_be_deleted": "Die Gruppe {group} kann nicht manuell entfernt werden.",
"group_cannot_edit_primary_group": "Die Gruppe '{group}' kann nicht manuell bearbeitet werden. Es ist die primäre Gruppe, welche dazu gedacht ist, nur ein spezifisches Konto zu enthalten.", "group_cannot_edit_primary_group": "Die Gruppe '{group}' kann nicht manuell bearbeitet werden. Es ist die primäre Gruppe, welche dazu gedacht ist, nur ein spezifisches Konto zu enthalten.",
"diagnosis_processes_killed_by_oom_reaper": "Das System hat einige Prozesse beendet, weil ihm der Arbeitsspeicher ausgegangen ist. Das passiert normalerweise, wenn das System ingesamt nicht genügend Arbeitsspeicher zur Verfügung hat oder wenn ein einzelner Prozess zu viel Speicher verbraucht. Zusammenfassung der beendeten Prozesse: \n{kills_summary}", "diagnosis_processes_killed_by_oom_reaper": "Das System hat ein paar Prozesse abgewürgt, da ihm der Speicher ausgegangen ist. Dies ist typischerweise sympomatisch eines ungenügenden Vorhandenseins des Arbeitsspeichers oder eines einzelnen Prozesses, der zu viel Speicher verbraucht. Zusammenfassung der abgewürgtenProzesse: \n{kills_summary}",
"diagnosis_description_ports": "Geöffnete Ports", "diagnosis_description_ports": "Geöffnete Ports",
"additional_urls_already_added": "Zusätzliche URL '{url}' bereits hinzugefügt in der zusätzlichen URL für Berechtigung '{permission}'", "additional_urls_already_added": "Zusätzliche URL '{url}' bereits hinzugefügt in der zusätzlichen URL für Berechtigung '{permission}'",
"additional_urls_already_removed": "Zusätzliche URL '{url}' bereits entfernt in der zusätzlichen URL für Berechtigung '{permission}'", "additional_urls_already_removed": "Zusätzliche URL '{url}' bereits entfernt in der zusätzlichen URL für Berechtigung '{permission}'",
"app_label_deprecated": "Dieser Befehl ist veraltet! Bitte nutze den neuen Befehl 'yunohost user permission update' um das Applabel zu verwalten.", "app_label_deprecated": "Dieser Befehl ist veraltet! Bitte nutze den neuen Befehl 'yunohost user permission update' um das Applabel zu verwalten.",
"diagnosis_http_hairpinning_issue_details": "Das liegt wahrscheinlich an deinem Router. Dadurch können Personen von ausserhalb deines Netzwerkes, aber nicht von innerhalb deines lokalen Netzwerkes (wie wahrscheinlich du selbst), auf deinen Server zugreifen, wenn dazu die Domäne oder öffentliche IP verwendet wird. Du kannst das Problem eventuell beheben, indem du ein einen Blick auf <a href='https://yunohost.org/dns_local_network'>https://yunohost.org/dns_local_network</a> wirfst", "diagnosis_http_hairpinning_issue_details": "Das liegt wahrscheinlich an Ihrem Router. Dadurch können Personen von ausserhalb deines Netzwerkes, aber nicht von innerhalb deines lokalen Netzwerkes (wie wahrscheinlich Sie selbst), auf Ihren Server zugreifen, wenn dazu die Domäne oder öffentliche IP verwendet wird. Sie können das Problem eventuell beheben, indem Sie einen Blick auf <a href='https://yunohost.org/dns_local_network'>https://yunohost.org/dns_local_network</a> werfen",
"diagnosis_http_nginx_conf_not_up_to_date": "Die Konfiguration von Nginx scheint für diese Domäne manuell geändert worden zu sein. Dies hindert YunoHost daran festzustellen, ob es über HTTP erreichbar ist.", "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_http_bad_status_code": "Es sieht so aus als ob ein anderes Gerät (vielleicht dein Router/Modem) anstelle Ihres 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üfen Sie ob Ihre Firewall oder Reverse-Proxy die Verbindung stören.",
"diagnosis_never_ran_yet": "Es sieht so aus, als wäre dieser Server erst kürzlich eingerichtet worden und es gibt noch keinen Diagnosebericht, der angezeigt werden könnte. Sie sollten zunächst eine vollständige Diagnose durchführen, entweder über die Web-Oberfläche oder mit \"yunohost diagnosis run\" von der Kommandozeile aus.", "diagnosis_never_ran_yet": "Es sieht so aus, als wäre dieser Server erst kürzlich eingerichtet worden und es gibt noch keinen Diagnosebericht, der angezeigt werden könnte. Sie sollten zunächst eine vollständige Diagnose durchführen, entweder über die Web-Oberfläche oder mit \"yunohost diagnosis run\" von der Kommandozeile aus.",
"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, um die Unterschiede anzuzeigen. Wenn Sie damit einverstanden sind, können Sie mit <cmd>yunohost tools regen-conf nginx --force</cmd> die Änderungen übernehmen.", "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, um die Unterschiede anzuzeigen. 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 vermutlich 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, was Sie tun.", "diagnosis_backports_in_sources_list": "Sie haben vermutlich 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, was Sie tun.",
@ -411,8 +411,8 @@
"group_already_exist_on_system_but_removing_it": "Die Gruppe {group} existiert bereits in den Systemgruppen, aber YunoHost wird sie entfernen...", "group_already_exist_on_system_but_removing_it": "Die Gruppe {group} existiert bereits in den Systemgruppen, aber YunoHost wird sie entfernen...",
"group_already_exist_on_system": "Die Gruppe {group} existiert bereits in den Systemgruppen", "group_already_exist_on_system": "Die Gruppe {group} existiert bereits in den Systemgruppen",
"group_already_exist": "Die Gruppe {group} existiert bereits", "group_already_exist": "Die Gruppe {group} existiert bereits",
"global_settings_setting_smtp_relay_password": "SMTP Relay Host Passwort", "global_settings_setting_smtp_relay_password": "SMTP-Relais-Passwort",
"global_settings_setting_smtp_relay_user": "SMTP Relay Benutzer Account", "global_settings_setting_smtp_relay_user": "SMTP-Relais-Benutzeraccount",
"global_settings_setting_smtp_relay_port": "SMTP Relay Port", "global_settings_setting_smtp_relay_port": "SMTP Relay Port",
"domain_cannot_remove_main_add_new_one": "Sie können '{domain}' nicht entfernen, da es die Hauptdomäne und Ihre einzige Domäne ist. Sie müssen zuerst eine andere Domäne mit 'yunohost domain add <domäne.com>' hinzufügen, dann als Hauptdomäne mit 'yunohost domain main-domain -n <domäne.com>' festlegen und dann können Sie die Domäne '{domain}' mit 'yunohost domain remove {domain}' entfernen'.'", "domain_cannot_remove_main_add_new_one": "Sie können '{domain}' nicht entfernen, da es die Hauptdomäne und Ihre einzige Domäne ist. Sie müssen zuerst eine andere Domäne mit 'yunohost domain add <domäne.com>' hinzufügen, dann als Hauptdomäne mit 'yunohost domain main-domain -n <domäne.com>' festlegen und dann können Sie die Domäne '{domain}' mit 'yunohost domain remove {domain}' entfernen'.'",
"diagnosis_rootfstotalspace_critical": "Das Root-Filesystem hat noch freien Speicher von {space}. Das ist besorngiserregend! Der Speicher wird schnell aufgebraucht sein. 16 GB für das Root-Filesystem werden empfohlen.", "diagnosis_rootfstotalspace_critical": "Das Root-Filesystem hat noch freien Speicher von {space}. Das ist besorngiserregend! Der Speicher wird schnell aufgebraucht sein. 16 GB für das Root-Filesystem werden empfohlen.",
@ -446,8 +446,8 @@
"log_domain_add": "Hinzufügen der Domäne '{}' zur Systemkonfiguration", "log_domain_add": "Hinzufügen der Domäne '{}' zur Systemkonfiguration",
"log_remove_on_failed_install": "Entfernen von '{}' nach einer fehlgeschlagenen Installation", "log_remove_on_failed_install": "Entfernen von '{}' nach einer fehlgeschlagenen Installation",
"domain_remove_confirm_apps_removal": "Wenn du diese Domäne löschst, werden folgende Applikationen entfernt:\n{apps}\n\nBist du sicher? [{answers}]", "domain_remove_confirm_apps_removal": "Wenn du diese Domäne löschst, werden folgende Applikationen entfernt:\n{apps}\n\nBist du sicher? [{answers}]",
"migrations_pending_cant_rerun": "Diese Migrationen sind immer noch anstehend und können deshalb nicht erneut durchgeführt werden: {ids}", "migrations_pending_cant_rerun": "Diese Migrationen sind immer noch ausstehend und können deshalb nicht erneut durchgeführt werden: {ids}",
"migrations_not_pending_cant_skip": "Diese Migrationen sind nicht anstehend und können deshalb nicht übersprungen werden: {ids}", "migrations_not_pending_cant_skip": "Diese Migrationen sind nicht ausstehend und können deshalb nicht übersprungen werden: {ids}",
"migrations_success_forward": "Migration {id} abgeschlossen", "migrations_success_forward": "Migration {id} abgeschlossen",
"migrations_dependencies_not_satisfied": "Führe diese Migrationen aus: '{dependencies_id}', bevor du {id} migrierst.", "migrations_dependencies_not_satisfied": "Führe diese Migrationen aus: '{dependencies_id}', bevor du {id} migrierst.",
"migrations_failed_to_load_migration": "Konnte Migration nicht laden {id}: {error}", "migrations_failed_to_load_migration": "Konnte Migration nicht laden {id}: {error}",
@ -505,14 +505,14 @@
"restore_system_part_failed": "Die Systemteile '{part}' konnten nicht wiederhergestellt werden", "restore_system_part_failed": "Die Systemteile '{part}' konnten nicht wiederhergestellt werden",
"restore_removing_tmp_dir_failed": "Ein altes, temporäres Directory konnte nicht entfernt werden", "restore_removing_tmp_dir_failed": "Ein altes, temporäres Directory konnte nicht entfernt werden",
"restore_not_enough_disk_space": "Nicht genug Speicher (Speicher: {free_space} B, benötigter Speicher: {needed_space} B, Sicherheitspuffer: {margin} B)", "restore_not_enough_disk_space": "Nicht genug Speicher (Speicher: {free_space} B, benötigter Speicher: {needed_space} B, Sicherheitspuffer: {margin} B)",
"restore_may_be_not_enough_disk_space": "Dein System scheint nicht genug Speicherplatz zu haben (frei: {free_space} B, benötigter Platz: {needed_space} B, Sicherheitspuffer: {margin} B)", "restore_may_be_not_enough_disk_space": "Ihr System scheint nicht genug Speicherplatz zu haben (frei: {free_space} B, benötigter Platz: {needed_space} B, Sicherheitspuffer: {margin} B)",
"restore_extracting": "Packe die benötigten Dateien aus dem Archiv aus...", "restore_extracting": "Auspacken der benötigten Dateien aus dem Archiv...",
"restore_already_installed_apps": "Folgende Apps können nicht wiederhergestellt werden, weil sie schon installiert sind: {apps}", "restore_already_installed_apps": "Folgende Apps können nicht wiederhergestellt werden, weil sie schon installiert sind: {apps}",
"regex_with_only_domain": "Du kannst regex nicht als Domain verwenden, sondern nur als Pfad", "regex_with_only_domain": "Sie können regex nicht als Domain verwenden, sondern nur als Pfad",
"root_password_desynchronized": "Das Admin-Passwort wurde geändert, aber YunoHost konnte dies nicht auf das Root-Passwort übertragen!", "root_password_desynchronized": "Das Admin-Passwort wurde geändert, aber YunoHost konnte dies nicht auf das Root-Passwort übertragen!",
"regenconf_need_to_explicitly_specify_ssh": "Die SSH-Konfiguration wurde manuell modifiziert, aber du musst explizit die Kategorie 'SSH' mit --force spezifizieren, um die Änderungen tatsächlich anzuwenden.", "regenconf_need_to_explicitly_specify_ssh": "Die SSH-Konfiguration wurde manuell modifiziert, aber Sie müssen explizit die Kategorie 'SSH' mit --force spezifizieren, um die Änderungen tatsächlich anzuwenden.",
"log_backup_create": "Erstelle ein Backup-Archiv", "log_backup_create": "Erstelle ein Backup-Archiv",
"diagnosis_sshd_config_inconsistent": "Es sieht aus, als ob der SSH-Port manuell geändert wurde in /etc/ssh/ssh_config. Seit YunoHost 4.2 ist eine neue globale Einstellung 'security.ssh.port' verfügbar um zu verhindern, dass die Konfiguration manuell verändert wird.", "diagnosis_sshd_config_inconsistent": "Es scheint wie wenn der SSH-Port in /etc/ssh/sshd_config manuell verändert wurde. Seit YunoHost 4.2 ist eine neue globale Einstellung 'security.ssh.ssh_port' verfügbar, um zu verhindern, dass die Konfiguration händisch verändert wird.",
"diagnosis_sshd_config_insecure": "Die SSH-Konfiguration wurde scheinbar manuell geändert und ist unsicher, weil sie keine 'AllowGroups'- oder 'AllowUsers' -Direktiven für die Beschränkung des Zugriffs durch autorisierte Benutzer enthält.", "diagnosis_sshd_config_insecure": "Die SSH-Konfiguration wurde scheinbar manuell geändert und ist unsicher, weil sie keine 'AllowGroups'- oder 'AllowUsers' -Direktiven für die Beschränkung des Zugriffs durch autorisierte Benutzer enthält.",
"backup_create_size_estimation": "Das Archiv wird etwa {size} an Daten enthalten.", "backup_create_size_estimation": "Das Archiv wird etwa {size} an Daten enthalten.",
"app_restore_script_failed": "Im Wiederherstellungsskript der Applikation ist ein Fehler aufgetreten", "app_restore_script_failed": "Im Wiederherstellungsskript der Applikation ist ein Fehler aufgetreten",
@ -520,17 +520,17 @@
"migration_ldap_rollback_success": "Das System wurde zurückgesetzt.", "migration_ldap_rollback_success": "Das System wurde zurückgesetzt.",
"migration_ldap_migration_failed_trying_to_rollback": "Migrieren war nicht möglich... Versuch, ein Rollback des Systems durchzuführen.", "migration_ldap_migration_failed_trying_to_rollback": "Migrieren war nicht möglich... Versuch, ein Rollback des Systems durchzuführen.",
"migration_ldap_backup_before_migration": "Vor der eigentlichen Migration ein Backup der LDAP-Datenbank und der Applikations-Einstellungen erstellen.", "migration_ldap_backup_before_migration": "Vor der eigentlichen Migration ein Backup der LDAP-Datenbank und der Applikations-Einstellungen erstellen.",
"global_settings_setting_ssowat_panel_overlay_enabled": "Das SSOwat-Overlay-Panel aktivieren", "global_settings_setting_ssowat_panel_overlay_enabled": "Das 'YunoHost'-Portalverknüpfungsquadrätchen bei den Apps aktivieren",
"diagnosis_sshd_config_inconsistent_details": "Bitte führe <cmd>yunohost settings set security.ssh.port -v YOUR_SSH_PORT</cmd> aus, um den SSH-Port festzulegen, und prüfe <cmd> yunohost tools regen-conf ssh --dry-run --with-diff</cmd> und <cmd>yunohost tools regen-conf ssh --force</cmd> um deine Konfiguration auf die YunoHost-Empfehlung zurückzusetzen.", "diagnosis_sshd_config_inconsistent_details": "Bitte führen Sie <cmd>yunohost settings set security.ssh.ssh_port -v YOUR_SSH_PORT</cmd> aus, um den SSH-Port festzulegen, und überprüfen Sie <cmd>yunohost tools regen-conf ssh --dry-run --with-diff</cmd> und <cmd>yunohost tools regen-conf ssh --force</cmd> um Ihre Konfiguration auf die YunoHost-Empfehlung zurückzusetzen.",
"regex_incompatible_with_tile": "/!\\ Packagers! Für Berechtigung '{permission}' ist show_tile auf 'true' gesetzt und deshalb kannst du keine regex-URL als Hauptdomäne setzen", "regex_incompatible_with_tile": "/!\\ Packagers! Für Berechtigung '{permission}' ist show_tile auf 'true' gesetzt und deshalb können Sie keine regex-URL als Hauptdomäne setzen",
"permission_cant_add_to_all_users": "Die Berechtigung {permission} kann nicht für allen Konten hinzugefügt werden.", "permission_cant_add_to_all_users": "Die Berechtigung {permission} kann nicht für allen Konten hinzugefügt werden.",
"migration_ldap_can_not_backup_before_migration": "Die Sicherung des Systems konnte nicht abgeschlossen werden, bevor die Migration fehlschlug. Fehler: {error}", "migration_ldap_can_not_backup_before_migration": "Die Sicherung des Systems konnte nicht abgeschlossen werden, bevor die Migration fehlschlug. Fehler: {error}",
"service_description_fail2ban": "Schützt gegen Brute-Force-Angriffe und andere Angriffe aus dem Internet", "service_description_fail2ban": "Schützt gegen Brute-Force-Angriffe und andere Angriffe aus dem Internet",
"service_description_dovecot": "Ermöglicht es E-Mail-Clients auf Konten zuzugreifen (IMAP und POP3)", "service_description_dovecot": "Ermöglicht es E-Mail-Clients auf Konten zuzugreifen (IMAP und POP3)",
"service_description_dnsmasq": "Verarbeitet die Auflösung des Domainnamens (DNS)", "service_description_dnsmasq": "Verwaltet die Auflösung des Domainnamens (DNS)",
"restore_backup_too_old": "Dieses Backup kann nicht wieder hergestellt werden, weil es von einer zu alten YunoHost Version stammt.", "restore_backup_too_old": "Dieses Backup kann nicht wieder hergestellt werden, weil es von einer zu alten YunoHost Version stammt.",
"service_description_slapd": "Speichert Konten, Domänen und verbundene Informationen", "service_description_slapd": "Speichert Konten, Domänen und verbundene Informationen",
"service_description_rspamd": "Spamfilter und andere E-Mail-Merkmale", "service_description_rspamd": "Spamfilter und andere E-Mail-Funktionen",
"service_description_redis-server": "Eine spezialisierte Datenbank für den schnellen Datenzugriff, die Aufgabenwarteschlange und die Kommunikation zwischen Programmen", "service_description_redis-server": "Eine spezialisierte Datenbank für den schnellen Datenzugriff, die Aufgabenwarteschlange und die Kommunikation zwischen Programmen",
"service_description_postfix": "Wird benutzt, um E-Mails zu senden und zu empfangen", "service_description_postfix": "Wird benutzt, um E-Mails zu senden und zu empfangen",
"service_description_nginx": "Stellt Daten aller Websiten auf dem Server bereit", "service_description_nginx": "Stellt Daten aller Websiten auf dem Server bereit",
@ -548,7 +548,7 @@
"this_action_broke_dpkg": "Diese Aktion hat unkonfigurierte Pakete verursacht, welche durch dpkg/apt (die Paketverwaltungen dieses Systems) zurückgelassen wurden... Du kannst versuchen dieses Problem zu lösen, indem du 'sudo apt install --fix-broken' und/oder 'sudo dpkg --configure -a' ausführst.", "this_action_broke_dpkg": "Diese Aktion hat unkonfigurierte Pakete verursacht, welche durch dpkg/apt (die Paketverwaltungen dieses Systems) zurückgelassen wurden... Du kannst versuchen dieses Problem zu lösen, indem du 'sudo apt install --fix-broken' und/oder 'sudo dpkg --configure -a' ausführst.",
"update_apt_cache_failed": "Kann den Cache von APT (Debians Paketmanager) nicht aktualisieren. Hier ist ein Auszug aus den sources.list-Zeilen, die helfen könnten, das Problem zu identifizieren:\n{sourceslist}", "update_apt_cache_failed": "Kann den Cache von APT (Debians Paketmanager) nicht aktualisieren. Hier ist ein Auszug aus den sources.list-Zeilen, die helfen könnten, das Problem zu identifizieren:\n{sourceslist}",
"unknown_main_domain_path": "Unbekannte Domäne oder Pfad für '{app}'. Sie müssen eine Domäne und einen Pfad angeben, um eine URL für die Genehmigung angeben zu können.", "unknown_main_domain_path": "Unbekannte Domäne oder Pfad für '{app}'. Sie müssen eine Domäne und einen Pfad angeben, um eine URL für die Genehmigung angeben zu können.",
"yunohost_postinstall_end_tip": "Post-install ist fertig! Um das Setup abzuschliessen, wird empfohlen:\n - ein erstes Konto über den Bereich 'Konto' im Adminbereich hinzuzufügen (oder mit 'yunohost user create <username>' in der Kommandezeile);\n - mögliche Fehler zu diagnostizieren über den Bereich 'Diagnose' im Adminbereich (oder mit 'yunohost diagnosis run' in der Kommandozeile;\n - Die Abschnitte 'Install YunoHost' und 'Geführte Tour' im Administratorenhandbuch zu lesen: https://yunohost.org/admindoc.", "yunohost_postinstall_end_tip": "Post-Installation ist fertig! Um das Setup abzuschliessen, wird folgendes empfohlen:\n - mögliche Fehler diagnostizieren im Bereich 'Diagnose' des Adminbereichs (oder mittels 'yunohost diagnosis run' in der Kommandozeile;\n - Die Abschnitte 'Install YunoHost' und 'Geführte Tour' im Administratorenhandbuch lesen: https://yunohost.org/admindoc.",
"user_already_exists": "Das Konto '{user}' ist bereits vorhanden", "user_already_exists": "Das Konto '{user}' ist bereits vorhanden",
"update_apt_cache_warning": "Beim Versuch den Cache für APT (Debians Paketmanager) zu aktualisieren, ist etwas schief gelaufen. Hier ist ein Dump der Zeilen aus sources.list, die Ihnen vielleicht dabei helfen, das Problem zu identifizieren:\n{sourceslist}", "update_apt_cache_warning": "Beim Versuch den Cache für APT (Debians Paketmanager) zu aktualisieren, ist etwas schief gelaufen. Hier ist ein Dump der Zeilen aus sources.list, die Ihnen vielleicht dabei helfen, das Problem zu identifizieren:\n{sourceslist}",
"disk_space_not_sufficient_update": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu aktualisieren", "disk_space_not_sufficient_update": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu aktualisieren",
@ -558,7 +558,7 @@
"config_apply_failed": "Anwenden der neuen Konfiguration fehlgeschlagen: {error}", "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_date": "Sollte ein zulässiges Datum in folgendem Format sein: YYYY-MM-DD",
"config_validate_email": "Sollte eine zulässige eMail sein", "config_validate_email": "Sollte eine zulässige eMail sein",
"config_forbidden_keyword": "Das Schlüsselwort '{keyword}' ist reserviert. Du kannst kein Konfigurationspanel mit einer Frage erstellen, die diese ID verwendet.", "config_forbidden_keyword": "Das Schlüsselwort '{keyword}' ist reserviert. Sie können kein Konfigurationspanel mit einer Frage erstellen, das diese ID verwendet.",
"config_no_panel": "Kein Konfigurationspanel gefunden.", "config_no_panel": "Kein Konfigurationspanel gefunden.",
"config_validate_color": "Sollte eine zulässige RGB hexadezimal Farbe sein", "config_validate_color": "Sollte eine zulässige RGB hexadezimal Farbe sein",
"diagnosis_apps_issue": "Ein Problem für die App {app} ist aufgetreten", "diagnosis_apps_issue": "Ein Problem für die App {app} ist aufgetreten",
@ -569,7 +569,7 @@
"diagnosis_apps_not_in_app_catalog": "Diese Applikation steht nicht im Applikationskatalog von YunoHost. Sie sollten in 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_not_in_app_catalog": "Diese Applikation steht nicht im Applikationskatalog von YunoHost. Sie sollten in 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 Applikation erfordert nur YunoHost >=2.x oder 3.x, was darauf hinweisen könnte, dass die Applikation nicht nach aktuell empfohlenen Paketierungspraktiken und mit aktuellen Helpern erstellt worden ist. Sie sollten wirklich in Betracht ziehen, sie zu aktualisieren.", "diagnosis_apps_outdated_ynh_requirement": "Die installierte Version dieser Applikation erfordert nur YunoHost >=2.x oder 3.x, was darauf hinweisen könnte, dass die Applikation nicht nach aktuell empfohlenen Paketierungspraktiken und mit aktuellen Helpern erstellt worden ist. Sie sollten wirklich in Betracht ziehen, sie zu aktualisieren.",
"diagnosis_description_apps": "Applikationen", "diagnosis_description_apps": "Applikationen",
"config_cant_set_value_on_section": "Du kannst einen einzelnen Wert nicht auf einen gesamten Konfigurationsbereich anwenden.", "config_cant_set_value_on_section": "Sie können einen einzelnen Wert nicht auf einen gesamten Konfigurationsbereich anwenden.",
"diagnosis_apps_deprecated_practices": "Die installierte Version dieser Applikation verwendet gewisse veraltete Paketierungspraktiken. Sie sollten sie wirklich aktualisieren.", "diagnosis_apps_deprecated_practices": "Die installierte Version dieser Applikation verwendet gewisse veraltete Paketierungspraktiken. Sie sollten sie wirklich aktualisieren.",
"app_config_unable_to_apply": "Konnte die Werte des Konfigurations-Panels nicht anwenden.", "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.", "app_config_unable_to_read": "Konnte die Werte des Konfigurations-Panels nicht auslesen.",
@ -624,7 +624,7 @@
"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})", "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_config_set": "Konfiguration für die Domäne '{}' aktualisieren",
"log_domain_dns_push": "DNS-Einträge für die Domäne '{}' übertragen", "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", "service_description_yunomdns": "Ermöglicht es Ihnen, den Server über 'yunohost.local' in Ihrem lokalen Netzwerk zu erreichen",
"migration_0021_start": "Beginnen von Migration zu Bullseye", "migration_0021_start": "Beginnen von Migration zu Bullseye",
"migration_0021_patching_sources_list": "Aktualisieren der sources.lists...", "migration_0021_patching_sources_list": "Aktualisieren der sources.lists...",
"migration_0021_main_upgrade": "Starte Hauptupdate...", "migration_0021_main_upgrade": "Starte Hauptupdate...",
@ -654,7 +654,7 @@
"global_settings_setting_admin_strength": "Stärke des Admin-Passworts", "global_settings_setting_admin_strength": "Stärke des Admin-Passworts",
"global_settings_setting_user_strength": "Stärke des Anmeldepassworts", "global_settings_setting_user_strength": "Stärke des Anmeldepassworts",
"global_settings_setting_postfix_compatibility_help": "Kompatibilitäts- vs. Sicherheits-Kompromiss für den Postfix-Server. Betrifft die Ciphers (und andere sicherheitsrelevante Aspekte)", "global_settings_setting_postfix_compatibility_help": "Kompatibilitäts- vs. Sicherheits-Kompromiss für den Postfix-Server. Betrifft die Ciphers (und andere sicherheitsrelevante Aspekte)",
"global_settings_setting_ssh_compatibility_help": "Kompatibilitäts- vs. Sicherheits-Kompromiss für den SSH-Server. Betrifft die Ciphers (und andere sicherheitsrelevante Aspekte)", "global_settings_setting_ssh_compatibility_help": "Kompatibilitäts- vs. Sicherheits-Kompromiss für den SSH-Server. Betrifft die Ciphers (und andere sicherheitsrelevante Aspekte). Bei Bedarf können Sie in https://infosec.mozilla.org/guidelines/openssh die Informationen nachlesen.",
"global_settings_setting_ssh_password_authentication_help": "Passwort-Authentifizierung für SSH zulassen", "global_settings_setting_ssh_password_authentication_help": "Passwort-Authentifizierung für SSH zulassen",
"global_settings_setting_ssh_port": "SSH-Port", "global_settings_setting_ssh_port": "SSH-Port",
"global_settings_setting_webadmin_allowlist_help": "IP-Adressen, die auf die Verwaltungsseite zugreifen dürfen. Kommasepariert.", "global_settings_setting_webadmin_allowlist_help": "IP-Adressen, die auf die Verwaltungsseite zugreifen dürfen. Kommasepariert.",
@ -677,7 +677,7 @@
"config_forbidden_readonly_type": "Der Typ '{type}' kann nicht auf Nur-Lesen eingestellt werden. Verwenden Sie bitte einen anderen Typ, um diesen Wert zu generieren (relevante ID des Arguments: '{id}').", "config_forbidden_readonly_type": "Der Typ '{type}' kann nicht auf Nur-Lesen eingestellt werden. Verwenden Sie bitte einen anderen Typ, um diesen Wert zu generieren (relevante ID des Arguments: '{id}').",
"diagnosis_using_stable_codename": "<cmd>apt</cmd> (Paketmanager des Systems) ist gegenwärtig konfiguriert um die Pakete des Code-Namens 'stable' zu installieren, anstelle die des Code-Namen der aktuellen Debian-Version (bullseye).", "diagnosis_using_stable_codename": "<cmd>apt</cmd> (Paketmanager des Systems) ist gegenwärtig konfiguriert um die Pakete des Code-Namens 'stable' zu installieren, anstelle die des Code-Namen der aktuellen Debian-Version (bullseye).",
"domain_config_acme_eligible": "Geeignet für ACME", "domain_config_acme_eligible": "Geeignet für ACME",
"diagnosis_using_stable_codename_details": "Dies wird meistens durch eine fehlerhafte Konfiguration seitens des Hosting-Providers verursacht. Dies stellt eine Gefahr dar, weil sobald die nächste Debian-Version zum neuen 'stable' wird, wird <cmd>apt</cmd> alle System-Pakete aktualisieren wollen, ohne eine ordnungsgemässe Migration zu durchlaufen. Es wird sehr empfohlen dies zu berichtigen, indem Sie die Datei der apt-Quellen des Debian-Basis-Repositorys entsprechend anpassen indem Sie das <cmd>stable</cmd>-Keyword durch <cmd>bullseye</cmd> ersetzen. Die zugehörige Konfigurationsdatei sollte <cmd>/etc/apt/sources.list</cmd> oder eine Datei im Verzeichnis <cmd>/etc/apt/sources.list.d/</cmd>sein.", "diagnosis_using_stable_codename_details": "Dies hat meistens eine fehlerhafte Konfiguration seitens Hosting-Provider zur Ursache. Dies stellt eine Gefahr dar, da sobald die nächste Debian-Version zum neuen 'stable' wird, führt <cmd>apt</cmd> eine Aktualisierung aller System-Pakete durch, ohne eine ordnungsgemässe Migration zu durchlaufen. Es wird dringlich darauf hingewiesen, dies zu berichtigen indem Sie die Datei der apt-Quellen des Debian-Base-Repositorys entsprechend anpassen indem Sie das <cmd>stable</cmd>-Keyword durch <cmd>bullseye</cmd> ersetzen. Die zugehörige Konfigurationsdatei sollte <cmd>/etc/apt/sources.list</cmd> oder eine Datei im Verzeichnis <cmd>/etc/apt/sources.list.d/</cmd>sein.",
"diagnosis_using_yunohost_testing": "<cmd>apt</cmd> (der Paketmanager des Systems) ist aktuell so konfiguriert, dass die 'testing'-Upgrades für YunoHost core installiert werden.", "diagnosis_using_yunohost_testing": "<cmd>apt</cmd> (der Paketmanager des Systems) ist aktuell so konfiguriert, dass die 'testing'-Upgrades für YunoHost core installiert werden.",
"diagnosis_using_yunohost_testing_details": "Dies ist wahrscheinlich OK, wenn Sie wissen, was Sie tun. Aber beachten Sie bitte die Release-Notes bevor sie zukünftige YunoHost-Upgrades installieren! Wenn Sie die 'testing'-Upgrades deaktivieren möchten, sollten sie das <cmd>testing</cmd>-Schlüsselwort aus <cmd>/etc/apt/sources.list.d/yunohost.list</cmd> entfernen.", "diagnosis_using_yunohost_testing_details": "Dies ist wahrscheinlich OK, wenn Sie wissen, was Sie tun. Aber beachten Sie bitte die Release-Notes bevor sie zukünftige YunoHost-Upgrades installieren! Wenn Sie die 'testing'-Upgrades deaktivieren möchten, sollten sie das <cmd>testing</cmd>-Schlüsselwort aus <cmd>/etc/apt/sources.list.d/yunohost.list</cmd> entfernen.",
"global_settings_setting_security_experimental_enabled": "Experimentelle Sicherheitsfunktionen", "global_settings_setting_security_experimental_enabled": "Experimentelle Sicherheitsfunktionen",
@ -704,5 +704,67 @@
"app_not_enough_ram": "Diese App benötigt {required} RAM um installiert/aktualisiert zu werden, aber es sind aktuell nur {current} verfügbar.", "app_not_enough_ram": "Diese App benötigt {required} RAM um installiert/aktualisiert zu werden, aber es sind aktuell nur {current} verfügbar.",
"app_change_url_failed": "Kann die URL für {app} nicht ändern: {error}", "app_change_url_failed": "Kann die URL für {app} nicht ändern: {error}",
"app_change_url_script_failed": "Es ist ein Fehler im URL-Änderungs-Script aufgetreten", "app_change_url_script_failed": "Es ist ein Fehler im URL-Änderungs-Script aufgetreten",
"app_resource_failed": "Automatische Ressourcen-Allokation (provisioning), die Unterbindung des Zugriffts auf Ressourcen (deprovisioning) oder die Aktualisierung der Ressourcen für {app} schlug fehl: {error}" "app_resource_failed": "Automatische Ressourcen-Allokation (provisioning), die Unterbindung des Zugriffts auf Ressourcen (deprovisioning) oder die Aktualisierung der Ressourcen für {app} schlug fehl: {error}",
"domain_config_cert_validity": "Validität",
"confirm_notifications_read": "WARNUNG: Sie sollten die App-Benachrichtigungen anschauen bevor sie weitermachen. Es könnte da Dinge geben, die gut zu wissen sein könnten. [{answers}]",
"domain_cannot_add_muc_upload": "Domänen, welche mit 'muc.' beginnen, können/dürfen Sie nicht hinzufügen. Dieser Namens-Typ ist reserviert für das in YunoHost integrierte XMPP-Multiuser-Chat-Feature.",
"domain_config_cert_summary_selfsigned": "WARNUNG: Aktuelles Zertifikat ist selbstssigniert. Browser werden neuen Besuchern eine furchteinflössende Warnung anzeigen!",
"app_failed_to_download_asset": "Konnte die Ressource '{source_id}' ({url}) für {app} nicht herunterladen: {out}",
"apps_failed_to_upgrade_line": "\n * {app_id} (um den zugehörigen Log anzuzeigen, führen Sie ein 'yunohost log show {operation_logger_name}' aus)",
"confirm_app_insufficient_ram": "GEFAHR! Diese App braucht {required} RAM um zu installieren/upgraden wobei momentan aber nur {current} vorhanden sind. Auch wenn diese App laufen könnte, würde ihr Installations- bzw. ihr Upgrade-Prozess eine grosse Menge an RAM brauchen, so dass Ihr Server anhalten und schrecklich versagen würde. Wenn Sie dieses Risiko einfach hinnehmen möchten, tippen Sie '{answers}'",
"diagnosis_ip_no_ipv6_tip_important": "IPv6 sollte, sofern verfügbar, üblicherweise automatisch durch das System oder Ihren Provider konfiguriert werden. Andernfalls kann es notwendig sein, dass Sie ein paar Dinge selbst, händisch konfigurieren, wie es die Dokumentation erklärt: <a href='https://yunohost.org/#/ipv6'>https://yunohost.org/#/ipv6</a>.",
"app_corrupt_source": "YunoHost konnte die Ressource '{source_id}' ({url}) für {app} herunterladen, aber die Ressource stimmt mit der erwarteten Checksum nicht überein. Dies könnte entweder bedeuten, dass Ihr Server einfach ein vorübergehendes Netzwerkproblem hatte ODER dass der Upstream-Betreuer (oder ein schädlicher/arglistiger Akteur) die Ressource auf eine bestimmte Art verändert hat und dass die YunoHost-Paketierer das App-Manifest untersuchen und so aktualisieren müssen, dass es diese Veränderung reflektiert.\n Erwartete sha256-Prüfsumme: {expected_sha256}\n Heruntergeladene sha256-Prüfsumme: {computed_sha256}\n Heruntergeladene Dateigrösse: {size}",
"global_settings_reset_success": "Reinitialisieren der globalen Einstellungen",
"global_settings_setting_root_password_confirm": "Neues root-Passwort (Bestätigung)",
"global_settings_setting_ssh_compatibility": "SSH-Kompatibilität",
"group_mailalias_remove": "Der E-Mail-Alias '{mail}' wird von der Gruppe '{group}' entfernt",
"group_user_add": "Der Benutzer '{user}' wird der Gruppe '{group}' hinzugefügt werden",
"global_settings_setting_nginx_compatibility": "NGINX-Kompatibilität",
"global_settings_setting_passwordless_sudo": "Erlauben Sie Administratoren 'sudo' zu benützen, ohne das Passwort erneut einzugeben",
"global_settings_setting_smtp_allow_ipv6": "Autorisiere das IPv6",
"domain_config_default_app_help": "Personen werden automatisch zu dieser App weitergeleitet, wenn sie diese Domäne öffnen. Wenn keine App spezifiziert wurde, werden Personen zum Benutzerportal-Login-Formular weitergeleitet.",
"domain_config_xmpp_help": "NB: ein paar XMPP-Features werden voraussetzen, dass Sie Ihre DNS-Einträge aktualisieren und Ihr Lets-Encrypt-Zertifikat neu erstellen, um eingeschaltet zu werden",
"global_settings_setting_smtp_relay_host": "Adresse des SMTP-Relais",
"global_settings_setting_nginx_redirect_to_https": "HTTPS erzwingen",
"group_no_change": "Nichts zu ändern für die Gruppe '{group}'",
"global_settings_setting_admin_strength_help": "Diese Parameter werden nur bei einer Initiailisierung oder einer Passwortänderung anwandt",
"global_settings_setting_backup_compress_tar_archives": "Datensicherungen komprimieren",
"global_settings_setting_dns_exposure_help": "NB: Dies beinflusst nur die vorgeschlagenen DNS-Konfigurations- und -Diagnose-Überprüfungen. Dies beeinflusst keine Systemkonfigurationen.",
"global_settings_setting_pop3_enabled": "POP3 einschalten",
"global_settings_setting_pop3_enabled_help": "POP3-Protokoll für den Mail-Server aktivieren",
"global_settings_setting_portal_theme_help": "Weitere Informationen dazu, wie Custom-Portal-Themes kreiert werden können unter https://yunohost.org/theming",
"global_settings_setting_postfix_compatibility": "Postfix-Kompatibilität",
"global_settings_setting_root_password": "Neues root-Passwort",
"global_settings_setting_user_strength_help": "Diese Parameter werden nur bei einer Initialisierung des oder Änderung des Passworts angewandt",
"global_settings_setting_webadmin_allowlist": "Allowlist für die Webadmin-IPs",
"global_settings_setting_webadmin_allowlist_enabled": "Webadmin-IP-Allowlist aktivieren",
"group_update_aliases": "Aktualisieren der Aliase für die Gruppe '{group}'",
"global_settings_setting_portal_theme": "Portal-Theme",
"global_settings_setting_smtp_relay_enabled": "Aktiviere das SMTP-Relais",
"global_settings_setting_dns_exposure": "Bei DNS-Konfiguration und -Diagnose zu berücksichtigende IP-Versionen",
"global_settings_setting_root_access_explain": "Auf Linux-Systemen ist 'root' der absolute Administrator. Im Kontext von YunoHost ist der direkte 'root'-SSH-Login standardmässig deaktiviert - ausgenommen des lokalen Netzwerks des Servers. Mitglieder der 'admins'-Gruppe sind in der Lage mit dem 'sudo'-Befehl in der Kommandozeile (CLI) als root zu agieren. Nun kann es hilfreich sein, ein (robustes) root-Passwort zu haben um das System zu debuggen oder für den Fall, dass sich die regulären Administratoren nicht mehr einloggen können.",
"global_settings_setting_ssh_password_authentication": "Authentifizieren mit Passwort",
"group_mailalias_add": "Der E-Mail-Alias '{mail}' wird der Gruppe '{group}' hinzugefügt",
"group_user_remove": "Der Benutzer '{user}' wird von der Gruppe '{group}' entfernt werden",
"invalid_credentials": "Ungültiges Passwort oder Benutzername",
"invalid_shell": "Ungültiger Shell: {shell}",
"migration_description_0025_global_settings_to_configpanel": "Migrieren der Legacy-Global-Einstellungsnomenklatur zur neuen, modernen Nomenklatur",
"root_password_changed": "Das root-Passwort wurde geändert",
"password_too_long": "Bitte wählen Sie ein Passwort aus, das weniger als 127 Zeichen hat",
"registrar_infos": "Registrar-Informationen (Herausgeber der Domainnamen/Domänennamen)",
"migration_0024_rebuild_python_venv_in_progress": "Probiere die Erneuerung der Python-virtualenv für `{app}`",
"migration_description_0024_rebuild_python_venv": "Reparieren der Python-Applikation nach Bullseye-Migration",
"migration_0024_rebuild_python_venv_disclaimer_rebuild": "Erneuerung der virtualenv wird für die folgenden Applikationen versucht (NB: die Operation kann einige Zeit in Anspruch nehmen!): {rebuild_apps}",
"log_resource_snippet": "Provisioning/Deprovisioning/Aktualisieren einer Ressource",
"log_settings_reset_all": "alle Parameter rücksetzen",
"log_settings_set": "Parameter anwenden",
"password_confirmation_not_the_same": "Das Passwort und die Bestätigung stimmen nicht überein",
"log_settings_reset": "Einstellungen rücksetzen",
"migration_0024_rebuild_python_venv_broken_app": "Ignoriere {app} weil virtualenv für diese Applikation nicht auf einfache Weise neu gebaut werden kann. Stattdessen sollten Sie die Situation berichtigen indem Sie das Aktualisieren der Applikation erzwingen indem Sie `yunohost app upgrade --force {app}`nutzen.",
"migration_0024_rebuild_python_venv_failed": "Fehler aufgetreten bei der Erneuerung der Python-virtualenv für Applikation {app}. Die Applikation kann nicht mehr funktionieren solange die Situation nicht behoben worden ist. Sie sollten diesen Umstand durch eine erzwungene Aktualisierung für diese Applikation beheben indem Sie `yunohost app upgrade --force {app}`benützen.",
"migration_description_0026_new_admins_group": "Migrieren in das neue 'Multiple-Administratoren'-Managementsystem (mehrere Benutzer können in der Gruppe 'Administratoren' präsent sein, mit allen Rechten von Administratoren auf der ganzen YunoHost-Instanz)",
"pattern_fullname": "Muss ein gültiger voller Name sein (mindestens 3 Zeichen)",
"migration_0021_not_buster2": "Die aktuelle Debian-Distribution ist nicht Buster! Wenn Sie bereits eine Buster->Bullseye-Migration durchgeführt haben, dann ist dieser Fehler symptomatisch für den Umstand, dass das Migrationsprozedere nicht zu 100% erfolgreich war (andernfalls hätte Yunohost es als vollständig gekennzeichnet). Es ist empfehlenswert, sich der Geschehnisse zusammen mit dem Support-Team anzunehmen, das einen Bedarf an einem **vollständigen** Log der Migration haben wird, das in Werkzeuge > Logs im Adminpanel auffindbar ist.",
"migration_0024_rebuild_python_venv_disclaimer_base": "Der Aktualisierung zu Debian Bullseye folgend ist es nötig, dass ein paar Python-Applikationen partiell neu gebaut und in die neue, mit Debian mitgelieferte Python-Version konvertiert werden. (in technischen Begrifflichkeiten: das, was wir die 'virtualenv' nennen, muss erneuert werden). In der Zwischenzeit kann es sein, dass diese Python-Applikationen nicht funktionieren. YunoHost kann versuchen die virtualenv für ein paar davon zu erneuern, wie untenstehend detailliert beschrieben wird. Für die anderen Applikationen, oder für den Fall, dass die Erneuerung fehlschlägt, werden eine erzwungene Aktualisierung für diese Applikationen durchführen müssen.",
"migration_0024_rebuild_python_venv_disclaimer_ignored": "Virtualenvs können für diese Applikationen nicht automatisch erneuert werden. Für diejenigen werden Sie eine erzwungene Aktualisierung durchführen müssen, was in der Kommandozeile bewerkstelligt werden kann mit: `yunohost app upgrade --force APP`: {ignored_apps}"
} }

View file

@ -1,8 +1,8 @@
{ {
"aborting": "Aborting.", "aborting": "Aborting.",
"action_invalid": "Invalid action '{action}'", "action_invalid": "Invalid action '{action}'",
"additional_urls_already_added": "Additionnal URL '{url}' already added in the additional URL for permission '{permission}'", "additional_urls_already_added": "Additional URL '{url}' already added in the additional URL for permission '{permission}'",
"additional_urls_already_removed": "Additionnal URL '{url}' already removed in the additional URL for permission '{permission}'", "additional_urls_already_removed": "Additional URL '{url}' already removed in the additional URL for permission '{permission}'",
"admin_password": "Administration password", "admin_password": "Administration password",
"admins": "Admins", "admins": "Admins",
"all_users": "All YunoHost users", "all_users": "All YunoHost users",
@ -90,6 +90,9 @@
"ask_new_domain": "New domain", "ask_new_domain": "New domain",
"ask_new_path": "New path", "ask_new_path": "New path",
"ask_password": "Password", "ask_password": "Password",
"ask_dyndns_recovery_password_explain": "Please pick a recovery password for your DynDNS domain, in case you need to reset it later.",
"ask_dyndns_recovery_password": "DynDNS recovery password",
"ask_dyndns_recovery_password_explain_during_unsubscribe": "Please enter the recovery password for this DynDNS domain.",
"ask_user_domain": "Domain to use for the user's email address and XMPP account", "ask_user_domain": "Domain to use for the user's email address and XMPP account",
"backup_abstract_method": "This backup method has yet to be implemented", "backup_abstract_method": "This backup method has yet to be implemented",
"backup_actually_backuping": "Creating a backup archive from the collected files...", "backup_actually_backuping": "Creating a backup archive from the collected files...",
@ -382,7 +385,6 @@
"domain_dns_registrar_supported": "YunoHost automatically detected that this domain is handled by the registrar **{registrar}**. If you want, YunoHost will automatically configure this DNS zone, if you provide it with the appropriate API credentials. You can find documentation on how to obtain your API credentials on this page: https://yunohost.org/registar_api_{registrar}. (You can also manually configure your DNS records following the documentation at https://yunohost.org/dns )", "domain_dns_registrar_supported": "YunoHost automatically detected that this domain is handled by the registrar **{registrar}**. If you want, YunoHost will automatically configure this DNS zone, if you provide it with the appropriate API credentials. You can find documentation on how to obtain your API credentials on this page: https://yunohost.org/registar_api_{registrar}. (You can also manually configure your DNS records following the documentation at https://yunohost.org/dns )",
"domain_dns_registrar_yunohost": "This domain is a nohost.me / nohost.st / ynh.fr and its DNS configuration is therefore automatically handled by YunoHost without any further configuration. (see the 'yunohost dyndns update' command)", "domain_dns_registrar_yunohost": "This domain is a nohost.me / nohost.st / ynh.fr and its DNS configuration is therefore automatically handled by YunoHost without any further configuration. (see the 'yunohost dyndns update' command)",
"domain_dyndns_already_subscribed": "You have already subscribed to a DynDNS domain", "domain_dyndns_already_subscribed": "You have already subscribed to a DynDNS domain",
"domain_dyndns_root_unknown": "Unknown DynDNS root domain",
"domain_exists": "The domain already exists", "domain_exists": "The domain already exists",
"domain_hostname_failed": "Unable to set new hostname. This might cause an issue later (it might be fine).", "domain_hostname_failed": "Unable to set new hostname. This might cause an issue later (it might be fine).",
"domain_registrar_is_not_configured": "The registrar is not yet configured for domain {domain}.", "domain_registrar_is_not_configured": "The registrar is not yet configured for domain {domain}.",
@ -398,12 +400,21 @@
"dyndns_domain_not_provided": "DynDNS provider {provider} cannot provide domain {domain}.", "dyndns_domain_not_provided": "DynDNS provider {provider} cannot provide domain {domain}.",
"dyndns_ip_update_failed": "Could not update IP address to DynDNS", "dyndns_ip_update_failed": "Could not update IP address to DynDNS",
"dyndns_ip_updated": "Updated your IP on DynDNS", "dyndns_ip_updated": "Updated your IP on DynDNS",
"dyndns_key_generating": "Generating DNS key... It may take a while.",
"dyndns_key_not_found": "DNS key not found for the domain", "dyndns_key_not_found": "DNS key not found for the domain",
"dyndns_no_domain_registered": "No domain registered with DynDNS", "dyndns_no_domain_registered": "No domain registered with DynDNS",
"dyndns_no_recovery_password": "No recovery password specified! In case you loose control of this domain, you will need to contact an administrator in the YunoHost team!",
"dyndns_provider_unreachable": "Unable to reach DynDNS provider {provider}: either your YunoHost is not correctly connected to the internet or the dynette server is down.", "dyndns_provider_unreachable": "Unable to reach DynDNS provider {provider}: either your YunoHost is not correctly connected to the internet or the dynette server is down.",
"dyndns_registered": "DynDNS domain registered", "dyndns_subscribed": "DynDNS domain subscribed",
"dyndns_registration_failed": "Could not register DynDNS domain: {error}", "dyndns_subscribe_failed": "Could not subscribe DynDNS domain: {error}",
"dyndns_unsubscribe_failed": "Could not unsubscribe DynDNS domain: {error}",
"dyndns_unsubscribed": "DynDNS domain unsubscribed",
"dyndns_unsubscribe_denied": "Failed to unsubscribe domain: invalid credentials",
"dyndns_unsubscribe_already_unsubscribed": "Domain is already unsubscribed",
"dyndns_set_recovery_password_denied": "Failed to set recovery password: invalid key",
"dyndns_set_recovery_password_unknown_domain": "Failed to set recovery password: domain not registered",
"dyndns_set_recovery_password_invalid_password": "Failed to set recovery password: password is not strong enough",
"dyndns_set_recovery_password_failed": "Failed to set recovery password: {error}",
"dyndns_set_recovery_password_success": "Recovery password set!",
"dyndns_unavailable": "The domain '{domain}' is unavailable.", "dyndns_unavailable": "The domain '{domain}' is unavailable.",
"extracting": "Extracting...", "extracting": "Extracting...",
"field_invalid": "Invalid field '{}'", "field_invalid": "Invalid field '{}'",
@ -514,6 +525,7 @@
"log_domain_main_domain": "Make '{}' the main domain", "log_domain_main_domain": "Make '{}' the main domain",
"log_domain_remove": "Remove '{}' domain from system configuration", "log_domain_remove": "Remove '{}' domain from system configuration",
"log_dyndns_subscribe": "Subscribe to a YunoHost subdomain '{}'", "log_dyndns_subscribe": "Subscribe to a YunoHost subdomain '{}'",
"log_dyndns_unsubscribe": "Unsubscribe to a YunoHost subdomain '{}'",
"log_dyndns_update": "Update the IP associated with your YunoHost subdomain '{}'", "log_dyndns_update": "Update the IP associated with your YunoHost subdomain '{}'",
"log_help_to_get_failed_log": "The operation '{desc}' could not be completed. Please share the full log of this operation using the command 'yunohost log share {name}' to get help", "log_help_to_get_failed_log": "The operation '{desc}' could not be completed. Please share the full log of this operation using the command 'yunohost log share {name}' to get help",
"log_help_to_get_log": "To view the log of the operation '{desc}', use the command 'yunohost log show {name}'", "log_help_to_get_log": "To view the log of the operation '{desc}', use the command 'yunohost log show {name}'",

View file

@ -1,25 +1,25 @@
{ {
"password_too_simple_1": "パスワードは少なくとも8文字必要です", "password_too_simple_1": "パスワードは8文字以上である必要があります",
"aborting": "中止します。", "aborting": "中止します。",
"action_invalid": "不正なアクション {action}", "action_invalid": "不正なアクション {action}",
"additional_urls_already_added": "アクセス許可 '{permission}' に対する追加URLには {url} が既に追加されています", "additional_urls_already_added": "アクセス許可 '{permission}' に対する追加URLには {url} が既に追加されています",
"admin_password": "管理者パスワード", "admin_password": "管理者パスワード",
"app_action_cannot_be_ran_because_required_services_down": "このアクションを実行するには、次の必要なサービスが実行されている必要があります: {services} 。続行するには再起動してみてください (そして何故ダウンしているのか調査してください)。", "app_action_cannot_be_ran_because_required_services_down": "このアクションを実行するには、次の必要なサービスが実行されている必要があります: {services} 。続行するには再起動してみてください (そして何故実行されていないのか調査してください)。",
"app_action_failed": "{name} アプリのアクション {action}' に失敗しました", "app_action_failed": "アプリ{app}のアクション{action}の実行に失敗しました",
"app_argument_invalid": "引数 '{name}' の有効な値を選択してください: {error}", "app_argument_invalid": "引数 '{name}' の有効な値を選択してください: {error}",
"app_argument_password_no_default": "パスワード引数 '{name}' の解析中にエラーが発生しました: セキュリティ上の理由から、パスワード引数にデフォルト値を設定することはできません", "app_argument_password_no_default": "パスワード引数 '{name}' の解析中にエラーが発生しました: セキュリティ上の理由から、パスワード引数にデフォルト値を設定することはできません",
"app_argument_required": "{name} は必要です。", "app_argument_required": "引数 '{name}' が必要です",
"app_change_url_failed": "{app}のURLを変更できませんでした:{error}", "app_change_url_failed": "{app}のURLを変更できませんでした:{error}",
"app_change_url_identical_domains": "古いドメインと新しいドメイン/url_pathは同一であ( '{domain}{path}')、何もしません。", "app_change_url_identical_domains": "古いドメインと新しいドメイン/url_pathは同一であるため( '{domain}{path}')、何もしません。",
"app_change_url_script_failed": "URL 変更スクリプト内でエラーが発生しました", "app_change_url_script_failed": "URL 変更スクリプト内でエラーが発生しました",
"app_failed_to_upgrade_but_continue": "アプリの{failed_app}アップグレードに失敗しました。要求に応じて次のアップグレードに進みます。「yunohostログショー{operation_logger_name}」を実行して失敗ログを表示します", "app_failed_to_upgrade_but_continue": "アプリ {failed_app} のアップグレードに失敗しました。次のアップグレードに進むことも可能です。yunohost log show {operation_logger_name} を実行して失敗ログを表示します",
"app_full_domain_unavailable": "申し訳ありませんが、このアプリは独自のドメインにインストールする必要がありますが、他のアプリは既にドメイン '{domain}' にインストールされています。代わりに、このアプリ専用のサブドメインを使用できます。", "app_full_domain_unavailable": "申し訳ありませんが、このアプリは独自のドメインにインストールする必要がありますが、他のアプリは既にドメイン '{domain}' にインストールされています。代わりに、このアプリ専用のサブドメインを使用できます。",
"app_id_invalid": "不正なアプリID", "app_id_invalid": "不正なアプリID",
"app_install_failed": "インストールできません {app}:{error}", "app_install_failed": "インストールできません {app}:{error}",
"app_manifest_install_ask_password": "このアプリの管理パスワードを選択してください", "app_manifest_install_ask_password": "このアプリの管理パスワードを選択してください",
"app_manifest_install_ask_path": "このアプリをインストールするURLパス(ドメインの後)を選択します", "app_manifest_install_ask_path": "このアプリをインストールするURLパス(ドメインの後)を選択します",
"app_not_properly_removed": "{app}が正しく削除されていません", "app_not_properly_removed": "{app}が正しく削除されていません",
"app_not_upgraded": "アプリ「{failed_app}」のアップグレードに失敗したため、次のアプリのアップグレードがキャンセルされました: {apps}", "app_not_upgraded": "アプリ'{failed_app}'のアップグレードに失敗したため、次のアプリのアップグレードがキャンセルされました: {apps}",
"app_start_remove": "{app} を削除しています…", "app_start_remove": "{app} を削除しています…",
"app_start_restore": "{app} をリストアしています…", "app_start_restore": "{app} をリストアしています…",
"ask_main_domain": "メインドメイン", "ask_main_domain": "メインドメイン",
@ -32,7 +32,7 @@
"backup_actually_backuping": "収集したファイルからバックアップアーカイブを作成しています...", "backup_actually_backuping": "収集したファイルからバックアップアーカイブを作成しています...",
"backup_archive_corrupted": "バックアップアーカイブ {archive} は破損しているようです: {error}", "backup_archive_corrupted": "バックアップアーカイブ {archive} は破損しているようです: {error}",
"backup_archive_name_exists": "この名前のバックアップアーカイブはすでに存在します。", "backup_archive_name_exists": "この名前のバックアップアーカイブはすでに存在します。",
"backup_archive_name_unknown": "「{name}」という名前の不明なローカルバックアップアーカイブ", "backup_archive_name_unknown": "{name} という不明なローカルバックアップアーカイブ",
"backup_archive_open_failed": "バックアップアーカイブを開けませんでした", "backup_archive_open_failed": "バックアップアーカイブを開けませんでした",
"backup_archive_system_part_not_available": "このバックアップでは、システム部分 '{part}' を使用できません", "backup_archive_system_part_not_available": "このバックアップでは、システム部分 '{part}' を使用できません",
"backup_method_custom_finished": "カスタム バックアップ方法 '{method}' が完了しました", "backup_method_custom_finished": "カスタム バックアップ方法 '{method}' が完了しました",
@ -41,14 +41,14 @@
"certmanager_cert_install_failed": "{domains}のLets Encrypt 証明書のインストールに失敗しました", "certmanager_cert_install_failed": "{domains}のLets Encrypt 証明書のインストールに失敗しました",
"certmanager_cert_install_failed_selfsigned": "{domains} ドメインの自己署名証明書のインストールに失敗しました", "certmanager_cert_install_failed_selfsigned": "{domains} ドメインの自己署名証明書のインストールに失敗しました",
"certmanager_cert_install_success": "Lets Encrypt 証明書が {domain} にインストールされました", "certmanager_cert_install_success": "Lets Encrypt 証明書が {domain} にインストールされました",
"certmanager_cert_install_success_selfsigned": "ドメイン「{domain}」に自己署名証明書がインストールされました", "certmanager_cert_install_success_selfsigned": "ドメイン'{domain}'に自己署名証明書がインストールされました",
"certmanager_domain_dns_ip_differs_from_public_ip": "ドメイン '{domain}' の DNS レコードは、このサーバーの IP とは異なります。詳細については、診断の「DNSレコード」(基本)カテゴリを確認してください。最近 A レコードを変更した場合は、反映されるまでお待ちください (一部の DNS 伝達チェッカーはオンラインで入手できます)。(何をしているかがわかっている場合は、 '--no-checks'を使用してこれらのチェックをオフにします。", "certmanager_domain_dns_ip_differs_from_public_ip": "ドメイン '{domain}' の DNS レコードは、このサーバーの IP とは異なります。詳細については、診断の'DNSレコード'(基本)カテゴリを確認してください。最近 A レコードを変更した場合は、反映されるまでお待ちください (一部の DNS プロパゲーション チェッカーはオンラインで入手できます)。(何をしているかがわかっている場合は、 '--no-checks'を使用してこれらのチェックをオフにします。",
"certmanager_domain_http_not_working": "ドメイン{domain}はHTTP経由でアクセスできないようです。詳細については、診断の「Web」カテゴリを確認してください。(何をしているかがわかっている場合は、 '--no-checks'を使用してこれらのチェックをオフにします。", "certmanager_domain_http_not_working": "ドメイン{domain}はHTTP経由でアクセスできないようです。詳細については、診断の'Web'カテゴリを確認してください。(何をしているかがわかっている場合は、 '--no-checks'を使用してこれらのチェックをオフにします。",
"certmanager_unable_to_parse_self_CA_name": "自己署名機関の名前を解析できませんでした (ファイル: {file})", "certmanager_unable_to_parse_self_CA_name": "自己署名機関の名前をパースできませんでした (ファイル: {file})",
"certmanager_domain_not_diagnosed_yet": "ドメイン{domain}の診断結果はまだありません。診断セクションのカテゴリ「DNSレコード」と「Web」の診断を再実行して、ドメインが暗号化の準備ができているかどうかを確認してください。(または、何をしているかがわかっている場合は、「--no-checks」を使用してこれらのチェックをオフにします。", "certmanager_domain_not_diagnosed_yet": "ドメイン{domain}の診断結果はまだありません。診断セクションのカテゴリ'DNSレコード'と'Web'の診断を再実行して、ドメインの暗号化が準備できているかどうかを確認してください。(または、何をしているかがわかっている場合は、'--no-checks'を使用してこれらのチェックをオフにします。",
"confirm_app_insufficient_ram": "危険!このアプリのインストール/アップグレードには{required}RAMが必要ですが、現在利用可能なのは{current}だけです。このアプリを実行できたとしても、そのインストール/アップグレードプロセスには大量のRAMが必要なため、サーバーがフリーズして惨めに失敗する可能性があります。とにかくそのリスクを冒しても構わないと思っているなら、「{answers}」と入力してください", "confirm_app_insufficient_ram": "危険!このアプリのインストール/アップグレードには{required}RAMが必要ですが、現在利用可能なのは{current} だけです。このアプリを実行できたとしても、インストール/アップグレードには大量のRAMが必要なため、サーバーがフリーズして惨めに失敗する可能性があります。とにかくそのリスクを冒しても構わないと思っているなら'{answers}'と入力してください",
"confirm_notifications_read": "警告:続行する前に上記のアプリ通知を確認する必要があります知っておくべき重要なことがあるかもしれません。[{answers}]", "confirm_notifications_read": "警告: 続行する前に上記のアプリ通知を確認する必要があります知っておくべき重要なことがあるかもしれません。[{answers}]",
"custom_app_url_required": "カスタム App をアップグレードするには URL を指定する必要があります{app}", "custom_app_url_required": "カスタム App {app} をアップグレードするには URL を指定する必要があります",
"danger": "危険:", "danger": "危険:",
"diagnosis_cant_run_because_of_dep": "{dep}に関連する重要な問題がある間、{category}診断を実行できません。", "diagnosis_cant_run_because_of_dep": "{dep}に関連する重要な問題がある間、{category}診断を実行できません。",
"diagnosis_description_apps": "アプリケーション", "diagnosis_description_apps": "アプリケーション",
@ -85,8 +85,8 @@
"diagnosis_security_vulnerable_to_meltdown": "Meltdown(重大なセキュリティの脆弱性)に対して脆弱に見えます", "diagnosis_security_vulnerable_to_meltdown": "Meltdown(重大なセキュリティの脆弱性)に対して脆弱に見えます",
"diagnosis_services_conf_broken": "サービス{service}の構成が壊れています!", "diagnosis_services_conf_broken": "サービス{service}の構成が壊れています!",
"diagnosis_services_running": "サービス{service}が実行されています!", "diagnosis_services_running": "サービス{service}が実行されています!",
"diagnosis_sshd_config_inconsistent": "SSHポートが/ etc / ssh / sshd_configで手動で変更されたようです。YunoHost 4.2以降、手動で構成を編集する必要がないように、新しいグローバル設定「security.ssh.ssh_port」を使用できます。", "diagnosis_sshd_config_inconsistent": "SSHポートが/etc/ssh/sshd_config で手動変更されたようです。YunoHost 4.2以降、手動で構成を編集する必要がないように、新しいグローバル設定'security.ssh.ssh_port'を使用できます。",
"diagnosis_swap_none": "システムにスワップがまったくない。システムのメモリ不足の状況を回避するために、少なくとも {recommended} つのスワップを追加することを検討する必要があります。", "diagnosis_swap_none": "システムにはスワップが {total} しかありません。システムのメモリ不足の状況を回避するために、少なくとも {recommended} のスワップを用意することを検討してください。",
"diagnosis_swap_notsomuch": "システムにはスワップが {total} しかありません。システムのメモリ不足の状況を回避するために、少なくとも {recommended} のスワップを用意することを検討してください。", "diagnosis_swap_notsomuch": "システムにはスワップが {total} しかありません。システムのメモリ不足の状況を回避するために、少なくとも {recommended} のスワップを用意することを検討してください。",
"diagnosis_swap_ok": "システムには {total} のスワップがあります!", "diagnosis_swap_ok": "システムには {total} のスワップがあります!",
"domain_cert_gen_failed": "証明書を生成できませんでした", "domain_cert_gen_failed": "証明書を生成できませんでした",
@ -100,13 +100,13 @@
"domain_dns_conf_special_use_tld": "このドメインは、.local や .test などの特殊な用途のトップレベル ドメイン (TLD) に基づいているため、実際の DNS レコードを持つことは想定されていません。", "domain_dns_conf_special_use_tld": "このドメインは、.local や .test などの特殊な用途のトップレベル ドメイン (TLD) に基づいているため、実際の DNS レコードを持つことは想定されていません。",
"domain_dns_push_already_up_to_date": "レコードはすでに最新であり、何もする必要はありません。", "domain_dns_push_already_up_to_date": "レコードはすでに最新であり、何もする必要はありません。",
"domain_dns_push_failed": "DNS レコードの更新が失敗しました。", "domain_dns_push_failed": "DNS レコードの更新が失敗しました。",
"domain_dyndns_already_subscribed": "すでに DynDNS ドメインにサブスクライブしてい", "domain_dyndns_already_subscribed": "すでに DynDNS ドメインにサブスクライブしています",
"dyndns_key_generating": "DNS キーを生成しています...しばらく時間がかかる場合があります。", "dyndns_key_generating": "DNS キーを生成しています...しばらく時間がかかる場合があります。",
"dyndns_key_not_found": "ドメインの DNS キーが見つかりません", "dyndns_key_not_found": "ドメインの DNS キーが見つかりません",
"firewall_reload_failed": "バックアップアーカイブを開けませんでした", "firewall_reload_failed": "ファイアウォールをリロードできませんでした",
"global_settings_setting_postfix_compatibility_help": "Postfix サーバーの互換性とセキュリティのトレードオフ。暗号(およびその他のセキュリティ関連の側面)に影響します", "global_settings_setting_postfix_compatibility_help": "Postfix サーバーの互換性とセキュリティにはトレードオフがあります。暗号(およびその他のセキュリティ関連の側面)に影響します",
"global_settings_setting_root_password": "新しい管理者パスワード", "global_settings_setting_root_password": "新しいルートパスワード",
"global_settings_setting_root_password_confirm": "新しい管理者パスワード", "global_settings_setting_root_password_confirm": "新しいルートパスワード(確認)",
"global_settings_setting_smtp_allow_ipv6": "IPv6 を許可する", "global_settings_setting_smtp_allow_ipv6": "IPv6 を許可する",
"global_settings_setting_user_strength_help": "これらの要件は、パスワードを初期化または変更する場合にのみ適用されます", "global_settings_setting_user_strength_help": "これらの要件は、パスワードを初期化または変更する場合にのみ適用されます",
"group_cannot_be_deleted": "グループ{group}を手動で削除することはできません。", "group_cannot_be_deleted": "グループ{group}を手動で削除することはできません。",
@ -122,37 +122,37 @@
"hook_exec_not_terminated": "スクリプトが正しく終了しませんでした: {path}", "hook_exec_not_terminated": "スクリプトが正しく終了しませんでした: {path}",
"log_app_install": "{} アプリをインストールする", "log_app_install": "{} アプリをインストールする",
"log_user_permission_update": "アクセス許可 '{}' のアクセスを更新する", "log_user_permission_update": "アクセス許可 '{}' のアクセスを更新する",
"log_user_update": "ユーザー '{}' の情報を更新する", "log_user_update": "ユーザー {name} を更新する",
"mail_alias_remove_failed": "電子メール エイリアス '{mail}' を削除できませんでした", "mail_alias_remove_failed": "電子メール エイリアス '{mail}' を削除できませんでした",
"mail_domain_unknown": "ドメイン '{domain}' の電子メール アドレスが無効です。このサーバーによって管理されているドメインを使用してください。", "mail_domain_unknown": "ドメイン '{domain}' の電子メール アドレスが無効です。このサーバーによって管理されているドメインを使用してください。",
"mail_forward_remove_failed": "電子メール転送 '{mail}' を削除できませんでした", "mail_forward_remove_failed": "電子メール転送 '{mail}' を削除できませんでした",
"mail_unavailable": "この電子メール アドレスは、管理者グループ用に予約されています", "mail_unavailable": "この電子メール アドレスは、管理者グループ用に予約されています",
"migration_0021_start": "Bullseyeへの移行開始", "migration_0021_start": "Bullseyeへの移行開始",
"migration_0021_yunohost_upgrade": "YunoHostコアのアップグレードを開始しています...", "migration_0021_yunohost_upgrade": "YunoHostコアのアップグレードを開始しています...",
"migration_description_0026_new_admins_group": "新しい「複数の管理者」システムに移行する", "migration_description_0026_new_admins_group": "新しい'複数の管理者'システムに移行する",
"migration_ldap_backup_before_migration": "実際の移行の前に、LDAP データベースとアプリ設定のバックアップを作成します。", "migration_ldap_backup_before_migration": "実際の移行の前に、LDAP データベースとアプリ設定のバックアップを作成します。",
"migration_ldap_can_not_backup_before_migration": "移行が失敗する前に、システムのバックアップを完了できませんでした。エラー: {error}", "migration_ldap_can_not_backup_before_migration": "移行が失敗する前に、システムのバックアップを完了できませんでした。エラー: {error}",
"migration_ldap_migration_failed_trying_to_rollback": "移行できませんでした...システムをロールバックしようとしています。", "migration_ldap_migration_failed_trying_to_rollback": "移行できませんでした...システムをロールバックしようとしています。",
"permission_updated": "アクセス許可 '{permission}' が更新されました", "permission_updated": "アクセス許可 '{permission}' が更新されました",
"restore_confirm_yunohost_installed": "すでにインストールされているシステムを復元しますか?[{answers}]", "restore_confirm_yunohost_installed": "すでにインストールされているシステムを復元しますか?[{answers}]",
"restore_extracting": "アーカイブから必要なファイルを抽出しています...", "restore_extracting": "アーカイブから必要なファイルを抽出しています...",
"restore_failed": "バックアップを復元する {name}", "restore_failed": "システムを復元できませんでした",
"restore_hook_unavailable": "「{part}」の復元スクリプトは、システムで使用できず、アーカイブでも利用できません", "restore_hook_unavailable": "'{part}'の復元スクリプトは、システムで使用できず、アーカイブでも利用できません",
"restore_not_enough_disk_space": "十分なスペースがありません(スペース:{free_space} B、必要なスペース:{needed_space} B、セキュリティマージン:{margin} B)", "restore_not_enough_disk_space": "十分なスペースがありません(スペース:{free_space} B、必要なスペース:{needed_space} B、セキュリティマージン:{margin} B)",
"restore_nothings_done": "何も復元されませんでした", "restore_nothings_done": "何も復元されませんでした",
"restore_removing_tmp_dir_failed": "古い一時ディレクトリを削除できませんでした", "restore_removing_tmp_dir_failed": "古い一時ディレクトリを削除できませんでした",
"restore_running_app_script": "アプリ「{app}」を復元しています...", "restore_running_app_script": "アプリ'{app}'を復元しています...",
"restore_running_hooks": "復元フックを実行しています...", "restore_running_hooks": "復元フックを実行しています...",
"restore_system_part_failed": "「{part}」システム部分を復元できませんでした", "restore_system_part_failed": "'{part}'システム部分を復元できませんでした",
"root_password_changed": "パスワード確認", "root_password_changed": "ルートのパスワードが変更されました",
"server_reboot": "サーバーが再起動します", "server_reboot": "サーバーが再起動します",
"server_shutdown_confirm": "サーバーはすぐにシャットダウンしますが、よろしいですか?[{answers}]", "server_shutdown_confirm": "サーバーはすぐにシャットダウンしますが、よろしいですか? [{answers}]",
"service_add_failed": "サービス '{service}' を追加できませんでした", "service_add_failed": "サービス '{service}' を追加できませんでした",
"service_added": "サービス '{service}' が追加されました", "service_added": "サービス '{service}' が追加されました",
"service_already_started": "サービス '{service}' は既に実行されています", "service_already_started": "サービス '{service}' は既に実行されています",
"service_description_dnsmasq": "ドメイン名解決 (DNS) を処理します", "service_description_dnsmasq": "ドメイン名解決 (DNS) を処理します",
"service_description_dovecot": "電子メールクライアントが電子メールにアクセス/フェッチすることを許可します(IMAPおよびPOP3経由)", "service_description_dovecot": "電子メールクライアントが電子メールにアクセス/フェッチすることを許可します(IMAPおよびPOP3経由)",
"service_description_fail2ban": "インターネットからのブルートフォース攻撃やその他の種類の攻撃から保護します", "service_description_fail2ban": "インターネットからのブルートフォース攻撃やその他の攻撃から保護します",
"service_description_metronome": "XMPP インスタント メッセージング アカウントを管理する", "service_description_metronome": "XMPP インスタント メッセージング アカウントを管理する",
"service_description_mysql": "アプリ データの格納 (SQL データベース)", "service_description_mysql": "アプリ データの格納 (SQL データベース)",
"service_description_postfix": "電子メールの送受信に使用", "service_description_postfix": "電子メールの送受信に使用",
@ -160,8 +160,8 @@
"service_enable_failed": "起動時にサービス '{service}' を自動的に開始できませんでした。\n\n最近のサービスログ:{logs}", "service_enable_failed": "起動時にサービス '{service}' を自動的に開始できませんでした。\n\n最近のサービスログ:{logs}",
"service_enabled": "サービス '{service}' は、システムの起動時に自動的に開始されるようになりました。", "service_enabled": "サービス '{service}' は、システムの起動時に自動的に開始されるようになりました。",
"service_reloaded": "サービス '{service}' がリロードされました", "service_reloaded": "サービス '{service}' がリロードされました",
"service_not_reloading_because_conf_broken": "構成が壊れているため、サービス「{name}」をリロード/再起動しません:{errors}", "service_not_reloading_because_conf_broken": "構成が壊れているため、サービス'{name}'をリロード/再起動しません: {errors}",
"show_tile_cant_be_enabled_for_regex": "権限 '{permission}' の URL は正規表現であるため、現在 'show_tile' を有効にすることはできません", "show_tile_cant_be_enabled_for_regex": "権限 '{permission}' の URL は正規表現であるため、現在 'show_tile' を有効にすることはできません",
"show_tile_cant_be_enabled_for_url_not_defined": "最初にアクセス許可 '{permission}' の URL を定義する必要があるため、現在 'show_tile' を有効にすることはできません。", "show_tile_cant_be_enabled_for_url_not_defined": "最初にアクセス許可 '{permission}' の URL を定義する必要があるため、現在 'show_tile' を有効にすることはできません。",
"ssowat_conf_generated": "SSOワット構成の再生成", "ssowat_conf_generated": "SSOワット構成の再生成",
"system_upgraded": "システムのアップグレード", "system_upgraded": "システムのアップグレード",
@ -170,26 +170,26 @@
"update_apt_cache_warning": "APT(Debianのパッケージマネージャー)のキャッシュを更新中に問題が発生しました。問題のある行を特定するのに役立つ可能性のあるsources.list行のダンプを次に示します。\n{sourceslist}", "update_apt_cache_warning": "APT(Debianのパッケージマネージャー)のキャッシュを更新中に問題が発生しました。問題のある行を特定するのに役立つ可能性のあるsources.list行のダンプを次に示します。\n{sourceslist}",
"admins": "管理者", "admins": "管理者",
"all_users": "YunoHostの全ユーザー", "all_users": "YunoHostの全ユーザー",
"already_up_to_date": "何もすることはありません。すべて最新です。", "already_up_to_date": "何もすることはありません。すべて最新です。",
"app_action_broke_system": "このアクションは、これらの重要なサービスを壊したようです: {services}", "app_action_broke_system": "このアクションは、これらの重要なサービスを壊したようです: {services}",
"app_already_installed": "アプリ '{app}' は既にインストール済み", "app_already_installed": "{app}は既にインストールされています",
"app_already_installed_cant_change_url": "このアプリは既にインストールされています。この機能だけではURLを変更することはできません。利用可能な場合は、`app changeurl`を確認してください。", "app_already_installed_cant_change_url": "このアプリは既にインストールされています。この機能だけではURLを変更することはできません。利用可能な場合は、`app changeurl`を確認してください。",
"app_already_up_to_date": "{app} アプリは既に最新です", "app_already_up_to_date": "{app} アプリは既に最新です",
"app_arch_not_supported": "このアプリはアーキテクチャ {required} にのみインストールできますが、サーバーのアーキテクチャは{current} です", "app_arch_not_supported": "このアプリはアーキテクチャ {required} にのみインストールできますが、サーバーのアーキテクチャは{current} です",
"app_argument_choice_invalid": "引数 '{name}' に有効な値を選択してください: '{value}' は使用可能な選択肢に含まれていません ({choices})", "app_argument_choice_invalid": "引数 '{name}' に有効な値を選択してください: '{value}' は使用可能な選択肢に含まれていません ({choices})",
"app_change_url_no_script": "アプリ「{app_name}」はまだURLの変更をサポートしていません。多分あなたはそれをアップグレードする必要があります。", "app_change_url_no_script": "アプリ {app_name} はまだURLの変更をサポートしていません。おそらく、あなたはそれをアップグレードする必要があります。",
"app_change_url_require_full_domain": "{app}は完全なドメイン(つまり、path = /)を必要とするため、この新しいURLに移動できません。", "app_change_url_require_full_domain": "{app}は完全なドメイン(つまり、path = /)を必要とするため、この新しいURLに移動できません。",
"app_change_url_success": "{app} URL が{domain}{path}されました", "app_change_url_success": "{app} URL は{domain}{path}になりました",
"app_config_unable_to_apply": "設定パネルの値を適用できませんでした。", "app_config_unable_to_apply": "設定パネルの値を適用できませんでした。",
"app_config_unable_to_read": "設定パネルの値の読み取りに失敗しました。", "app_config_unable_to_read": "設定パネルの値の読み取りに失敗しました。",
"app_corrupt_source": "YunoHost はアセット '{source_id}' ({url}) を {app} 用にダウンロードできましたが、アセットのチェックサムが期待されるものと一致しません。これは、あなたのサーバーで一時的なネットワーク障害が発生したか、もしくはアセットがアップストリームメンテナ(または悪意のあるアクター?)によって何らかの形で変更され、YunoHostパッケージャーがアプリマニフェストを調査/更新する必要があることを意味する可能性があります。\n 期待される sha256 チェックサム: {expected_sha256}\n ダウンロードしたsha256チェックサム: {computed_sha256}\n ダウンロードしたファイルサイズ: {size}", "app_corrupt_source": "YunoHost はアセット '{source_id}' ({url}) を {app} 用にダウンロードできましたが、アセットのチェックサムが期待されるものと一致しません。これは、あなたのサーバーで一時的なネットワーク障害が発生したか、もしくはアセットがアップストリームメンテナ(または悪意のあるアクター?)によって何らかの形で変更され、YunoHostパッケージャーがアプリマニフェストを調査/更新する必要があることを意味する可能性があります。\n 期待される sha256 チェックサム: {expected_sha256}\n ダウンロードしたsha256チェックサム: {computed_sha256}\n ダウンロードしたファイルサイズ: {size}",
"app_extraction_failed": "インストール ファイルを抽出できませんでした", "app_extraction_failed": "インストール ファイルを抽出できませんでした",
"app_failed_to_download_asset": "{app}のアセット「{source_id}」({url})をダウンロードできませんでした:{out}", "app_failed_to_download_asset": "{app}のアセット{source_id} ({url}) をダウンロードできませんでした: {out}",
"app_install_files_invalid": "これらのファイルはインストールできません", "app_install_files_invalid": "これらのファイルはインストールできません",
"app_install_script_failed": "アプリのインストールスクリプト内部でエラーが発生しました", "app_install_script_failed": "アプリのインストールスクリプト内部でエラーが発生しました",
"app_label_deprecated": "このコマンドは非推奨です。新しいコマンド yunohost user permission update を使用して、アプリラベルを管理してください。", "app_label_deprecated": "このコマンドは非推奨です。新しいコマンド yunohost user permission update を使用して、アプリラベルを管理してください。",
"app_location_unavailable": "この URL は利用できないか、既にインストールされているアプリと競合しています。\n{apps}", "app_location_unavailable": "この URL は利用できないか、既にインストールされているアプリと競合しています。\n{apps}",
"app_make_default_location_already_used": "「{app}」をドメインのデフォルトアプリにすることはできません。「{domain}」は「{other_app}」によってすでに使用されています", "app_make_default_location_already_used": "{app} をドメインのデフォルトアプリにすることはできません。’{domain}{other_app} によってすでに使用されています",
"app_manifest_install_ask_admin": "このアプリの管理者ユーザーを選択する", "app_manifest_install_ask_admin": "このアプリの管理者ユーザーを選択する",
"app_manifest_install_ask_domain": "このアプリをインストールするドメインを選択してください", "app_manifest_install_ask_domain": "このアプリをインストールするドメインを選択してください",
"app_manifest_install_ask_init_admin_permission": "このアプリの管理機能にアクセスできるのは誰ですか?(これは後で変更できます)", "app_manifest_install_ask_init_admin_permission": "このアプリの管理機能にアクセスできるのは誰ですか?(これは後で変更できます)",
@ -199,12 +199,12 @@
"app_not_enough_disk": "このアプリには{required}の空き容量が必要です。", "app_not_enough_disk": "このアプリには{required}の空き容量が必要です。",
"app_not_enough_ram": "このアプリのインストール/アップグレードには{required} のRAMが必要ですが、現在利用可能なのは {current} だけです。", "app_not_enough_ram": "このアプリのインストール/アップグレードには{required} のRAMが必要ですが、現在利用可能なのは {current} だけです。",
"app_not_installed": "インストールされているアプリのリストに{app}が見つかりませんでした: {all_apps}", "app_not_installed": "インストールされているアプリのリストに{app}が見つかりませんでした: {all_apps}",
"app_not_upgraded_broken_system": "アプリ「{failed_app}」はアップグレードに失敗し、システムを壊れた状態にしたため、次のアプリのアップグレードがキャンセルされました: {apps}", "app_not_upgraded_broken_system": "アプリ'{failed_app}'はアップグレードに失敗し、システムを壊れた状態にしたため、次のアプリのアップグレードがキャンセルされました: {apps}",
"app_not_upgraded_broken_system_continue": "アプリ {failed_app} はアップグレードに失敗し、システムを壊れた状態にした(そのためcontinue-on-failureは無視されます)ので、次のアプリのアップグレードがキャンセルされました: {apps}", "app_not_upgraded_broken_system_continue": "アプリ {failed_app} はアップグレードに失敗し、システムを壊れた状態にした(そのためcontinue-on-failureは無視されます)ので、次のアプリのアップグレードがキャンセルされました: {apps}",
"app_restore_failed": "{app}を復元できませんでした: {error}", "app_restore_failed": "{app}を復元できませんでした: {error}",
"app_restore_script_failed": "アプリのリストアスクリプト内でエラーが発生しました", "app_restore_script_failed": "アプリのリストアスクリプト内でエラーが発生しました",
"app_sources_fetch_failed": "ソースファイルをフェッチできませんでしたが、URLは正しいですか?", "app_sources_fetch_failed": "ソースファイルをフェッチできませんでしたが、URLは正しいですか?",
"app_packaging_format_not_supported": "このアプリは、パッケージ形式がYunoHostバージョンでサポートされていないため、インストールできません。おそらく、システムのアップグレードを検討する必要があります。", "app_packaging_format_not_supported": "このアプリは、パッケージ形式がこのYunoHostバージョンでサポートされていないため、インストールできません。おそらく、システムのアップグレードを検討する必要があります。",
"app_remove_after_failed_install": "インストールの失敗後にアプリを削除しています...", "app_remove_after_failed_install": "インストールの失敗後にアプリを削除しています...",
"app_removed": "'{app}' はアンインストール済", "app_removed": "'{app}' はアンインストール済",
"app_requirements_checking": "{app} の依存関係を確認しています…", "app_requirements_checking": "{app} の依存関係を確認しています…",
@ -224,7 +224,7 @@
"app_upgrade_some_app_failed": "一部のアプリをアップグレードできませんでした", "app_upgrade_some_app_failed": "一部のアプリをアップグレードできませんでした",
"app_upgraded": "'{app}' アップグレード済", "app_upgraded": "'{app}' アップグレード済",
"app_yunohost_version_not_supported": "このアプリは YunoHost >= {required} を必要としますが、現在インストールされているバージョンは{current} です", "app_yunohost_version_not_supported": "このアプリは YunoHost >= {required} を必要としますが、現在インストールされているバージョンは{current} です",
"apps_already_up_to_date": "全てのアプリが最新になりました", "apps_already_up_to_date": "全てのアプリが最新になりました",
"apps_catalog_failed_to_download": "{apps_catalog} アプリ カタログをダウンロードできません: {error}", "apps_catalog_failed_to_download": "{apps_catalog} アプリ カタログをダウンロードできません: {error}",
"apps_failed_to_upgrade": "これらのアプリケーションのアップグレードに失敗しました: {apps}", "apps_failed_to_upgrade": "これらのアプリケーションのアップグレードに失敗しました: {apps}",
"apps_failed_to_upgrade_line": "\n * {app_id} (対応するログを表示するには、yunohost log show {operation_logger_name} を実行してください)", "apps_failed_to_upgrade_line": "\n * {app_id} (対応するログを表示するには、yunohost log show {operation_logger_name} を実行してください)",
@ -239,7 +239,7 @@
"backup_archive_broken_link": "バックアップアーカイブにアクセスできませんでした({path}へのリンクが壊れています)", "backup_archive_broken_link": "バックアップアーカイブにアクセスできませんでした({path}へのリンクが壊れています)",
"backup_archive_cant_retrieve_info_json": "アーカイブ '{archive}' の情報を読み込めませんでした... info.json ファイルを取得できません (または有効な json ではありません)。", "backup_archive_cant_retrieve_info_json": "アーカイブ '{archive}' の情報を読み込めませんでした... info.json ファイルを取得できません (または有効な json ではありません)。",
"backup_archive_writing_error": "圧縮アーカイブ '{archive}' にバックアップするファイル '{source}' (アーカイブ '{dest}' で指定) を追加できませんでした", "backup_archive_writing_error": "圧縮アーカイブ '{archive}' にバックアップするファイル '{source}' (アーカイブ '{dest}' で指定) を追加できませんでした",
"backup_ask_for_copying_if_needed": "一時的に{size}MBを使用してバックアップを実行しますか?(この方法は、より効率的な方法で準備できなかったファイルがあるため、この方法が使用されます", "backup_ask_for_copying_if_needed": "一時的に{size}MBを使用してバックアップを実行しますか?(より効率的な方法で準備できなかったファイルがあるため、この方法が使用されます)",
"backup_cant_mount_uncompress_archive": "非圧縮アーカイブを書き込み保護としてマウントできませんでした", "backup_cant_mount_uncompress_archive": "非圧縮アーカイブを書き込み保護としてマウントできませんでした",
"backup_cleaning_failed": "一時バックアップフォルダをクリーンアップできませんでした", "backup_cleaning_failed": "一時バックアップフォルダをクリーンアップできませんでした",
"backup_copying_to_organize_the_archive": "アーカイブを整理するために{size}MBをコピーしています", "backup_copying_to_organize_the_archive": "アーカイブを整理するために{size}MBをコピーしています",
@ -249,8 +249,8 @@
"backup_creation_failed": "バックアップ作成できませんでした", "backup_creation_failed": "バックアップ作成できませんでした",
"backup_csv_addition_failed": "バックアップするファイルをCSVファイルに追加できませんでした", "backup_csv_addition_failed": "バックアップするファイルをCSVファイルに追加できませんでした",
"backup_csv_creation_failed": "復元に必要な CSV ファイルを作成できませんでした", "backup_csv_creation_failed": "復元に必要な CSV ファイルを作成できませんでした",
"backup_custom_backup_error": "カスタムバックアップ方法は「バックアップ」ステップを通過できませんでした", "backup_custom_backup_error": "カスタムバックアップ方法は'バックアップ'ステップを通過できませんでした",
"backup_custom_mount_error": "カスタムバックアップ方法は「マウント」ステップを通過できませんでした", "backup_custom_mount_error": "カスタムバックアップ方法は'マウント'ステップを通過できませんでした",
"backup_delete_error": "{path} を削除する", "backup_delete_error": "{path} を削除する",
"backup_deleted": "バックアップは削除されました: {name}", "backup_deleted": "バックアップは削除されました: {name}",
"backup_nothings_done": "保存するものがありません", "backup_nothings_done": "保存するものがありません",
@ -260,50 +260,50 @@
"backup_hook_unknown": "バックアップ フック '{hook}' が不明です", "backup_hook_unknown": "バックアップ フック '{hook}' が不明です",
"backup_method_copy_finished": "バックアップコピーがファイナライズされました", "backup_method_copy_finished": "バックアップコピーがファイナライズされました",
"backup_method_tar_finished": "TARバックアップアーカイブが作成されました", "backup_method_tar_finished": "TARバックアップアーカイブが作成されました",
"backup_output_symlink_dir_broken": "アーカイブディレクトリ '{path}' は壊れたシンボリックリンクです。たぶん、あなたはそれが指す記憶媒体を再/マウントまたは差し込むのを忘れました。", "backup_output_symlink_dir_broken": "アーカイブディレクトリ '{path}' は壊れたシンボリックリンクです。おそらく、リンク先の記憶媒体をマウント/再マウントし忘れたか、差し込むのを忘れたのではないかと。",
"backup_mount_archive_for_restore": "復元のためにアーカイブを準備しています...", "backup_mount_archive_for_restore": "復元のためにアーカイブを準備しています...",
"backup_no_uncompress_archive_dir": "そのような圧縮されていないアーカイブディレクトリはありません", "backup_no_uncompress_archive_dir": "そのような圧縮されていないアーカイブディレクトリはありません",
"certmanager_warning_subdomain_dns_record": "サブドメイン '{subdomain}' は '{domain}' と同じ IP アドレスに解決されません。一部の機能は、これを修正して証明書を再生成するまで使用できません。", "certmanager_warning_subdomain_dns_record": "サブドメイン '{subdomain}' は '{domain}' と同じ IP アドレスに解決されません。一部の機能は、これを修正して証明書を再生成するまで使用できません。",
"config_action_disabled": "アクション '{action}' は無効になっているため実行できませんでした。制約を満たしていることを確認してください。ヘルプ: {help}", "config_action_disabled": "アクション '{action}' は無効になっているため実行できませんでした。制約を満たしていることを確認してください。ヘルプ: {help}",
"backup_permission": "{app}のバックアップ権限", "backup_permission": "{app}のバックアップ権限",
"backup_running_hooks": "バックアップフックを実行しています...", "backup_running_hooks": "バックアップフックを実行しています...",
"backup_system_part_failed": "「{part}」システム部分をバックアップできませんでした", "backup_system_part_failed": "{part} システム部分をバックアップできませんでした",
"backup_unable_to_organize_files": "簡単な方法を使用してアーカイブ内のファイルを整理できませんでした", "backup_unable_to_organize_files": "急速な方法を使用してアーカイブ内のファイルを整理できませんでした",
"backup_with_no_backup_script_for_app": "アプリ「{app}」にはバックアップスクリプトがありません。無視。", "backup_with_no_backup_script_for_app": "アプリ {app} にはバックアップスクリプトがありません。無視します。",
"backup_with_no_restore_script_for_app": "{app}には復元スクリプトがないため、このアプリのバックアップを自動的に復元することはできません。", "backup_with_no_restore_script_for_app": "{app}には復元スクリプトがないため、このアプリのバックアップを自動的に復元することはできません。",
"certmanager_acme_not_configured_for_domain": "ACMEチャレンジは、nginx confに対応するコードスニペットがないため現在{domain}実行できません...'yunohost tools regen-conf nginx --dry-run --with-diff' を使用して、nginx の設定が最新であることを確認してください。", "certmanager_acme_not_configured_for_domain": "{domain}に対するACMEチャレンジは、nginx confに対応するコードスニペットがないため現在実行できません... 'yunohost tools regen-conf nginx --dry-run --with-diff' を使用して、nginx の設定が最新であることを確認してください。",
"certmanager_attempt_to_renew_nonLE_cert": "ドメイン '{domain}' の証明書は、Let's Encryptによって発行されていません。自動的に更新できません!", "certmanager_attempt_to_renew_nonLE_cert": "ドメイン '{domain}' の証明書は、Let's Encryptによって発行されていません。自動的に更新できません!",
"certmanager_attempt_to_renew_valid_cert": "ドメイン '{domain}' の証明書の有効期限が近づいていません。(あなたが何をしているのかわかっている場合は、--forceを使用できます)", "certmanager_attempt_to_renew_valid_cert": "ドメイン '{domain}' の証明書の有効期限が近づいていません。(あなたが何をしているのかわかっている場合は、--forceを使用できます)",
"certmanager_cert_renew_failed": "{domains}のLets Encrypt 証明書更新に失敗しました", "certmanager_cert_renew_failed": "{domains}のLets Encrypt 証明書更新に失敗しました",
"certmanager_cert_renew_success": "{domains}のLets Encrypt 証明書が更新されました", "certmanager_cert_renew_success": "{domain}のLets Encrypt 証明書が更新されました",
"certmanager_cert_signing_failed": "新しい証明書に署名できませんでした", "certmanager_cert_signing_failed": "新しい証明書に署名できませんでした",
"certmanager_certificate_fetching_or_enabling_failed": "{domain}に新しい証明書を使用しようとしましたが、機能しませんでした...", "certmanager_certificate_fetching_or_enabling_failed": "{domain}に新しい証明書を使用しようとしましたが、機能しませんでした...",
"certmanager_domain_cert_not_selfsigned": "ドメイン {domain} の証明書は自己署名されていません。置き換えてよろしいですか(これを行うには '--force' を使用してください)", "certmanager_domain_cert_not_selfsigned": "ドメイン {domain} の証明書は自己署名されていません。置き換えてよろしいですか(これを行うには '--force' を使用してください)",
"certmanager_hit_rate_limit": "最近{domain}、この正確なドメインのセットに対して既に発行されている証明書が多すぎます。しばらくしてからもう一度お試しください。詳細については、https://letsencrypt.org/docs/rate-limits/ を参照してください。", "certmanager_hit_rate_limit": "直近でドメイン {domain} に対して発行されている証明書が多すぎます。しばらくしてからもう一度お試しください。詳細については、https://letsencrypt.org/docs/rate-limits/ を参照してください。",
"certmanager_no_cert_file": "ドメイン {domain} (ファイル: {file}) の証明書ファイルを読み取れませんでした。", "certmanager_no_cert_file": "ドメイン {domain} (ファイル: {file}) の証明書ファイルを読み取れませんでした。",
"certmanager_self_ca_conf_file_not_found": "自己署名機関の設定ファイルが見つかりませんでした(ファイル:{file})", "certmanager_self_ca_conf_file_not_found": "自己署名機関の設定ファイルが見つかりませんでした(ファイル:{file})",
"config_forbidden_readonly_type": "型 '{type}' は読み取り専用として設定できず、別の型を使用してこの値をレンダリングします (関連する引数 ID: '{id}')。", "config_forbidden_readonly_type": "型 '{type}' は読み取り専用として設定できず、別の型を使用してこの値をレンダリングしてください (関連する引数 ID: '{id}')。",
"config_no_panel": "設定パネルが見つかりません。", "config_no_panel": "設定パネルが見つかりません。",
"config_unknown_filter_key": "フィルター キー '{filter_key}' が正しくありません。", "config_unknown_filter_key": "フィルター キー '{filter_key}' が正しくありません。",
"config_validate_color": "有効な RGB 16 進色である必要があります", "config_validate_color": "有効な RGB 16 進色である必要があります",
"config_validate_date": "YYYY-MM-DD の形式のような有効な日付である必要があります", "config_validate_date": "YYYY-MM-DD のような形式の有効な日付である必要があります",
"config_validate_email": "有効なメールアドレスである必要があります", "config_validate_email": "有効なメールアドレスである必要があります",
"config_action_failed": "アクション '{action}' の実行に失敗しました: {error}", "config_action_failed": "アクション '{action}' の実行に失敗しました: {error}",
"config_apply_failed": "新しい構成の適用に失敗しました: {error}", "config_apply_failed": "新しい設定の適用に失敗しました: {error}",
"config_cant_set_value_on_section": "構成セクション全体に 1 つの値を設定することはできません。", "config_cant_set_value_on_section": "設定セクション全体に 1 つの値を設定することはできません。",
"config_forbidden_keyword": "キーワード '{keyword}' は予約されており、この ID 質問を含む設定パネルを作成または使用することはできません。", "config_forbidden_keyword": "キーワード '{keyword}' は予約されており、この ID を持つ質問を含む設定パネルを作成または使用することはできません。",
"config_validate_time": "HH:MM のような有効な時刻である必要があります", "config_validate_time": "HH:MM のような有効な時刻である必要があります",
"config_validate_url": "有効なウェブ URL である必要があります", "config_validate_url": "有効なウェブ URL である必要があります",
"confirm_app_install_danger": "危険!このアプリはまだ実験的であることが知られています(明示的に動作していない場合)!あなたが何をしているのかわからない限り、おそらくそれをインストールしないでください。このアプリが機能しないか、システムを壊した場合、サポートは提供されません...とにかくそのリスクを冒しても構わないと思っているなら、「{answers}」と入力してください", "confirm_app_install_danger": "危険!このアプリはまだ実験的であることが知られています(明示的に動作しないとされていない場合)! 自分で何をしているのかわからない限り、それをインストールしないでください。このアプリが機能しないか、システムを壊した場合、サポートは提供されません... それでも、とにかくそのリスクを冒しても構わないと思っているなら、'{answers}'と入力してください",
"confirm_app_install_thirdparty": "危険このアプリはYunoHostのアプリカタログの一部ではありません。サードパーティのアプリをインストールすると、システムの整合性とセキュリティが損なわれる可能性があります。あなたが何をしているのかわからない限り、おそらくそれをインストールしないでください。このアプリが機能しないか、システムを壊した場合、サポートは提供されません...とにかくそのリスクを冒しても構わないと思っているなら、「{answers}」と入力してください", "confirm_app_install_thirdparty": "危険このアプリはYunoHostのアプリカタログの一部ではありません。サードパーティのアプリをインストールすると、システムの整合性とセキュリティが損なわれる可能性があります。あなたが何をしているのかわからない限り、それをインストールしないでください。このアプリが機能しないか、システムを壊した場合、サポートは提供されません... それでもとにかくそのリスクを冒しても構わないと思っているなら、'{answers}'と入力してください",
"confirm_app_install_warning": "警告:このアプリは動作する可能性がありますが、YunoHostにうまく統合されていません。シングル サインオンやバックアップ/復元などの一部の機能は使用できない場合があります。とにかくインストールしますか?[{answers}] ", "confirm_app_install_warning": "警告:このアプリは動作する可能性がありますが、YunoHostにうまく統合されていません。シングル サインオンやバックアップ/復元などの一部の機能は使用できない場合があります。とにかくインストールしますか? [{answers}] ",
"diagnosis_apps_allgood": "インストールされているすべてのアプリは、基本的なパッケージ化プラクティスを尊重します", "diagnosis_apps_allgood": "インストールされているすべてのアプリは、基本的なパッケージ化プラクティスを尊重します",
"diagnosis_apps_bad_quality": "このアプリケーションは現在、YunoHostのアプリケーションカタログで壊れているとフラグが付けられています。これは、メンテナが問題を修正しようとしている間の一時的な問題である可能性があります。それまでの間、このアプリのアップグレードは無効になります。", "diagnosis_apps_bad_quality": "このアプリケーションは現在、YunoHostのアプリケーションカタログで壊れているとフラグが付けられています。これは、メンテナが問題を修正しようとしている間の一時的な問題である可能性があります。それまでの間、このアプリのアップグレードは無効になります。",
"diagnosis_apps_broken": "このアプリケーションは現在、YunoHostのアプリケーションカタログで壊れているとフラグが付けられています。これは、メンテナが問題を修正しようとしている間の一時的な問題である可能性があります。それまでの間、このアプリのアップグレードは無効になります。", "diagnosis_apps_broken": "このアプリケーションは現在、YunoHostのアプリケーションカタログで壊れているとフラグが付けられています。これは、メンテナが問題を修正しようとしている間の一時的な問題である可能性があります。それまでの間、このアプリのアップグレードは無効になります。",
"diagnosis_apps_deprecated_practices": "このアプリのインストール済みバージョンでは、非常に古い非推奨のパッケージ化プラクティスがまだ使用されています。あなたは本当にそれをアップグレードすることを検討する必要があります。", "diagnosis_apps_deprecated_practices": "このアプリのインストール済みバージョンでは、非常に古い非推奨のパッケージ化プラクティスがまだ使用されています。あなたは本当にそれをアップグレードすることを検討する必要があります。",
"diagnosis_basesystem_hardware": "サーバーのハードウェア アーキテクチャが{virt} {arch}", "diagnosis_basesystem_hardware": "サーバーのハードウェア アーキテクチャが{virt} {arch}",
"diagnosis_basesystem_hardware_model": "サーバーモデルが{model}", "diagnosis_basesystem_hardware_model": "サーバーモデルが{model}",
"diagnosis_apps_issue": "アプリ '{app}' をアップグレードする", "diagnosis_apps_issue": "アプリ{app}で問題が見つかりました",
"diagnosis_apps_not_in_app_catalog": "このアプリケーションは、YunoHostのアプリケーションカタログにはありません。過去に存在し、削除された場合は、アップグレードを受け取らず、システムの整合性とセキュリティが損なわれる可能性があるため、このアプリのアンインストールを検討する必要があります。", "diagnosis_apps_not_in_app_catalog": "このアプリケーションは、YunoHostのアプリケーションカタログにはありません。過去に存在し、削除された場合は、アップグレードを受け取らず、システムの整合性とセキュリティが損なわれる可能性があるため、このアプリのアンインストールを検討する必要があります。",
"diagnosis_apps_outdated_ynh_requirement": "このアプリのインストール済みバージョンには、yunohost >= 2.xまたは3.xのみが必要であり、推奨されるパッケージングプラクティスとヘルパーが最新ではないことを示す傾向があります。あなたは本当にそれをアップグレードすることを検討する必要があります。", "diagnosis_apps_outdated_ynh_requirement": "このアプリのインストール済みバージョンには、yunohost >= 2.xまたは3.xのみが必要であり、推奨されるパッケージングプラクティスとヘルパーが最新ではないことを示す傾向があります。あなたは本当にそれをアップグレードすることを検討する必要があります。",
"diagnosis_backports_in_sources_list": "apt(パッケージマネージャー)はバックポートリポジトリを使用するように構成されているようです。あなたが何をしているのか本当にわからない限り、バックポートからパッケージをインストールすることは、システムに不安定性や競合を引き起こす可能性があるため、強くお勧めしません。", "diagnosis_backports_in_sources_list": "apt(パッケージマネージャー)はバックポートリポジトリを使用するように構成されているようです。あなたが何をしているのか本当にわからない限り、バックポートからパッケージをインストールすることは、システムに不安定性や競合を引き起こす可能性があるため、強くお勧めしません。",
@ -320,7 +320,7 @@
"diagnosis_diskusage_low": "ストレージ<code><0></0></code>(デバイス<code><1></1></code>上)には、( )残りの領域({free_percent} )しかありません{free}。{total}注意してください。", "diagnosis_diskusage_low": "ストレージ<code><0></0></code>(デバイス<code><1></1></code>上)には、( )残りの領域({free_percent} )しかありません{free}。{total}注意してください。",
"diagnosis_diskusage_ok": "ストレージ<code><0></0></code>(デバイス<code><1></1></code>上)にはまだ({free_percent}%)スペースが{free}残っています(から{total})!", "diagnosis_diskusage_ok": "ストレージ<code><0></0></code>(デバイス<code><1></1></code>上)にはまだ({free_percent}%)スペースが{free}残っています(から{total})!",
"diagnosis_diskusage_verylow": "ストレージ<code><0></0></code>(デバイス<code><1></1></code>上)には、( )残りの領域({free_percent} )しかありません{free}。{total}あなたは本当にいくつかのスペースをきれいにすることを検討する必要があります!", "diagnosis_diskusage_verylow": "ストレージ<code><0></0></code>(デバイス<code><1></1></code>上)には、( )残りの領域({free_percent} )しかありません{free}。{total}あなたは本当にいくつかのスペースをきれいにすることを検討する必要があります!",
"diagnosis_display_tip": "見つかった問題を確認するには、ウェブ管理者の診断セクションに移動するか、コマンドラインから「yunohost診断ショー--問題--人間が読める」を実行します。", "diagnosis_display_tip": "見つかった問題を確認するには、ウェブ管理者の診断セクションに移動するか、コマンドラインから'yunohost診断ショー--問題--人間が読める'を実行します。",
"diagnosis_dns_bad_conf": "一部の DNS レコードが見つからないか、ドメイン {domain} (カテゴリ {category}) が正しくない", "diagnosis_dns_bad_conf": "一部の DNS レコードが見つからないか、ドメイン {domain} (カテゴリ {category}) が正しくない",
"diagnosis_dns_discrepancy": "次の DNS レコードは、推奨される構成に従っていないようです。<br>種類: <code><0></0></code><br>名前: <code><1></1></code><br>現在の値: <code><2></2></code><br>期待値: <code><3></3></code>", "diagnosis_dns_discrepancy": "次の DNS レコードは、推奨される構成に従っていないようです。<br>種類: <code><0></0></code><br>名前: <code><1></1></code><br>現在の値: <code><2></2></code><br>期待値: <code><3></3></code>",
"diagnosis_dns_good_conf": "DNS レコードがドメイン {domain} (カテゴリ {category}) 用に正しく構成されている", "diagnosis_dns_good_conf": "DNS レコードがドメイン {domain} (カテゴリ {category}) 用に正しく構成されている",
@ -382,7 +382,7 @@
"diagnosis_package_installed_from_sury": "一部のシステムパッケージはダウングレードする必要があります", "diagnosis_package_installed_from_sury": "一部のシステムパッケージはダウングレードする必要があります",
"diagnosis_processes_killed_by_oom_reaper": "一部のプロセスは、メモリが不足したため、最近システムによって強制終了されました。これは通常、システム上のメモリ不足、またはプロセスがメモリを消費しすぎていることを示しています。強制終了されたプロセスの概要:\n{kills_summary}", "diagnosis_processes_killed_by_oom_reaper": "一部のプロセスは、メモリが不足したため、最近システムによって強制終了されました。これは通常、システム上のメモリ不足、またはプロセスがメモリを消費しすぎていることを示しています。強制終了されたプロセスの概要:\n{kills_summary}",
"diagnosis_ram_low": "システムには{available}({available_percent}%)の使用可能なRAMがあります({total}のうち)。注意してください。", "diagnosis_ram_low": "システムには{available}({available_percent}%)の使用可能なRAMがあります({total}のうち)。注意してください。",
"diagnosis_package_installed_from_sury_details": "一部のパッケージは、Suryと呼ばれるサードパーティのリポジトリから誤ってインストールされました。YunoHostチームはこれらのパッケージを処理する戦略を改善しましたが、Stretchを使用している間にPHP7.3アプリをインストールした一部のセットアップには、いくつかの矛盾が残っていると予想されます。この状況を修正するには、次のコマンドを実行してみてください <cmd>{cmd_to_fix}</cmd>", "diagnosis_package_installed_from_sury_details": "一部のパッケージは、Suryと呼ばれるサードパーティのリポジトリから誤ってインストールされました。YunoHostチームはこれらのパッケージを処理する戦略を改善しましたが、Debian Stretchを使用してPHP7.3アプリをインストールした一部のセットアップには、いくつかの点で一貫性のない状態であることが予想されます。この状況を修正するには、次のコマンドを実行してみてください: <cmd>{cmd_to_fix}</cmd>",
"diagnosis_ports_could_not_diagnose": "IPv{ipversion} で外部からポートに到達できるかどうかを診断できませんでした。", "diagnosis_ports_could_not_diagnose": "IPv{ipversion} で外部からポートに到達できるかどうかを診断できませんでした。",
"diagnosis_ports_could_not_diagnose_details": "エラー: {error}", "diagnosis_ports_could_not_diagnose_details": "エラー: {error}",
"diagnosis_ports_unreachable": "ポート {port} は外部から到達できません。", "diagnosis_ports_unreachable": "ポート {port} は外部から到達できません。",
@ -397,21 +397,21 @@
"diagnosis_services_bad_status": "サービス{service} のステータスは {status} です :(", "diagnosis_services_bad_status": "サービス{service} のステータスは {status} です :(",
"diagnosis_services_bad_status_tip": "サービスの再起動を試みることができ、それが機能しない場合は、<a href='#/services/{service}'>webadminの</a>サービスログを確認してください(コマンドラインから、yunohost<cmd>サービスの再起動{service}とyunohost</cmd><cmd>サービスログ{service}</cmd>を使用してこれを行うことができます)。<a href='#/services/{service}'></a>。", "diagnosis_services_bad_status_tip": "サービスの再起動を試みることができ、それが機能しない場合は、<a href='#/services/{service}'>webadminの</a>サービスログを確認してください(コマンドラインから、yunohost<cmd>サービスの再起動{service}とyunohost</cmd><cmd>サービスログ{service}</cmd>を使用してこれを行うことができます)。<a href='#/services/{service}'></a>。",
"diagnosis_sshd_config_inconsistent_details": "<cmd>security.ssh.ssh_port -v YOUR_SSH_PORT に設定された yunohost 設定</cmd>を実行して SSH ポートを定義し、yunohost tools regen-conf ssh --<cmd>dry-run --with-diff および yunohost tools regen-conf ssh --</cmd>force をチェックして、会議を <cmd>YunoHost</cmd> の推奨事項にリセットしてください。", "diagnosis_sshd_config_inconsistent_details": "<cmd>security.ssh.ssh_port -v YOUR_SSH_PORT に設定された yunohost 設定</cmd>を実行して SSH ポートを定義し、yunohost tools regen-conf ssh --<cmd>dry-run --with-diff および yunohost tools regen-conf ssh --</cmd>force をチェックして、会議を <cmd>YunoHost</cmd> の推奨事項にリセットしてください。",
"diagnosis_sshd_config_insecure": "SSH構成は手動で変更されたようで、許可されたユーザーへのアクセスを制限するための「許可グループ」または「許可ユーザー」ディレクティブが含まれていないため、安全ではありません。", "diagnosis_sshd_config_insecure": "SSH構成は手動で変更されたようで、許可されたユーザーへのアクセスを制限するための'許可グループ'または'許可ユーザー'ディレクティブが含まれていないため、安全ではありません。",
"diagnosis_swap_tip": "サーバーがSDカードまたはSSDストレージでスワップをホストしている場合、デバイスの平均寿命が大幅に短くなる可能性があることに注意してください。", "diagnosis_swap_tip": "サーバーがSDカードまたはSSDストレージでスワップをホストしている場合、デバイスの平均寿命が大幅に短くなる可能性があることに注意してください。",
"diagnosis_unknown_categories": "次のカテゴリは不明です: {categories}", "diagnosis_unknown_categories": "次のカテゴリは不明です: {categories}",
"diagnosis_using_stable_codename": "<cmd>apt</cmd> (システムのパッケージマネージャ) は現在、現在の Debian バージョン (bullseye) のコードネームではなく、コードネーム 'stable' からパッケージをインストールするように設定されています。", "diagnosis_using_stable_codename": "<cmd>apt</cmd> (システムのパッケージマネージャ) は現在、現在の Debian バージョン (bullseye) のコードネームではなく、コードネーム 'stable' からパッケージをインストールするように設定されています。",
"disk_space_not_sufficient_install": "このアプリケーションをインストールするのに十分なディスク領域が残っていません", "disk_space_not_sufficient_install": "このアプリケーションをインストールするのに十分なディスク領域が残っていません",
"diagnosis_using_stable_codename_details": "これは通常、ホスティングプロバイダーからの構成が正しくないことが原因です。なぜなら、Debian の次のバージョンが新しい「安定版」になるとすぐに、<cmd>apt</cmd> は適切な移行手順を経ずにすべてのシステムパッケージをアップグレードしたくなるからです。ベース Debian リポジトリの apt ソースを編集してこれを修正し、<cmd>安定版</cmd>キーワードを <cmd>bullseye</cmd> に置き換えることをお勧めします。対応する設定ファイルは /etc/apt/sources.list、または /<cmd>etc/apt/sources.list.d/</cmd> 内のファイルでなければなりません。<cmd></cmd>", "diagnosis_using_stable_codename_details": "これは通常、ホスティングプロバイダーからの構成が正しくないことが原因です。なぜなら、Debian の次のバージョンが新しい'安定版'になるとすぐに、<cmd>apt</cmd> は適切な移行手順を経ずにすべてのシステムパッケージをアップグレードしたくなるからです。ベース Debian リポジトリの apt ソースを編集してこれを修正し、<cmd>安定版</cmd>キーワードを <cmd>bullseye</cmd> に置き換えることをお勧めします。対応する設定ファイルは /etc/apt/sources.list、または /<cmd>etc/apt/sources.list.d/</cmd> 内のファイルでなければなりません。<cmd></cmd>",
"diagnosis_using_yunohost_testing": "<cmd>apt</cmd> (システムのパッケージマネージャー)は現在、YunoHostコアの「テスト」アップグレードをインストールするように構成されています。", "diagnosis_using_yunohost_testing": "<cmd>apt</cmd> (システムのパッケージマネージャー)は現在、YunoHostコアの'テスト'アップグレードをインストールするように構成されています。",
"diagnosis_using_yunohost_testing_details": "自分が何をしているのかを知っていれば、これはおそらく問題ありませんが、YunoHostのアップグレードをインストールする前にリリースートに注意してください!「テスト版」のアップグレードを無効にしたい場合は、/<cmd>etc/apt/sources.list.d/yunohost.list</cmd> から <cmd>testing</cmd> キーワードを削除する必要があります。", "diagnosis_using_yunohost_testing_details": "自分が何をしているのかを知っていれば、これはおそらく問題ありませんが、YunoHostのアップグレードをインストールする前にリリースートに注意してください!'テスト版'のアップグレードを無効にしたい場合は、/<cmd>etc/apt/sources.list.d/yunohost.list</cmd> から <cmd>testing</cmd> キーワードを削除する必要があります。",
"disk_space_not_sufficient_update": "このアプリケーションを更新するのに十分なディスク領域が残っていません", "disk_space_not_sufficient_update": "このアプリケーションを更新するのに十分なディスク領域が残っていません",
"domain_cannot_add_muc_upload": "「muc.」で始まるドメインを追加することはできません。この種の名前は、YunoHostに統合されたXMPPマルチユーザーチャット機能のために予約されています。", "domain_cannot_add_muc_upload": "'muc.'で始まるドメインを追加することはできません。この種の名前は、YunoHostに統合されたXMPPマルチユーザーチャット機能のために予約されています。",
"domain_cannot_add_xmpp_upload": "「xmpp-upload」で始まるドメインを追加することはできません。この種の名前は、YunoHostに統合されたXMPPアップロード機能のために予約されています。", "domain_cannot_add_xmpp_upload": "'xmpp-upload'で始まるドメインを追加することはできません。この種の名前は、YunoHostに統合されたXMPPアップロード機能のために予約されています。",
"domain_cannot_remove_main": "'{domain}'はメインドメインなので削除できないので、まず「yunohost domain main-domain -n」を使用して別のドメインをメインドメインとして設定する必要があります。 候補 <another-domain>ドメインのリストは次のとおりです。 {other_domains}</another-domain>", "domain_cannot_remove_main": "'{domain}'はメインドメインなので削除できないので、まず'yunohost domain main-domain -n'を使用して別のドメインをメインドメインとして設定する必要があります。 候補 <another-domain>ドメインのリストは次のとおりです。 {other_domains}</another-domain>",
"domain_config_api_protocol": "API プロトコル", "domain_config_api_protocol": "API プロトコル",
"domain_cannot_remove_main_add_new_one": "「{domain}」はメインドメインであり唯一のドメインであるため、最初に「yunohostドメイン追加<another-domain.com>」を使用して別のドメインを追加し、次に「yunohostドメインメインドメイン-n <another-domain.com>」を使用してメインドメインとして設定し、「yunohostドメイン削除{domain}」を使用してドメイン「{domain}」を削除する必要があります。", "domain_cannot_remove_main_add_new_one": "'{domain}'はメインドメインであり唯一のドメインであるため、最初に'yunohostドメイン追加<another-domain.com>'を使用して別のドメインを追加し、次に'yunohostドメインメインドメイン-n <another-domain.com>'を使用してメインドメインとして設定し、'yunohostドメイン削除{domain}'を使用してドメイン'{domain}'を削除する必要があります。",
"domain_config_acme_eligible_explain": "このドメインは、Let's Encrypt証明書の準備ができていないようです。DNS 構成と HTTP サーバーの到達可能性を確認してください。 <a href='#/diagnosis'>診断ページの</a> 「DNSレコード」と「Web」セクションは、何が誤って構成されているかを理解するのに役立ちます。", "domain_config_acme_eligible_explain": "このドメインは、Let's Encrypt証明書の準備ができていないようです。DNS 構成と HTTP サーバーの到達可能性を確認してください。 <a href='#/diagnosis'>診断ページの</a> 'DNSレコード'と'Web'セクションは、何が誤って構成されているかを理解するのに役立ちます。",
"domain_config_auth_application_key": "アプリケーションキー", "domain_config_auth_application_key": "アプリケーションキー",
"domain_config_auth_application_secret": "アプリケーション秘密鍵", "domain_config_auth_application_secret": "アプリケーション秘密鍵",
"domain_config_auth_consumer_key": "消費者キー", "domain_config_auth_consumer_key": "消費者キー",
@ -447,57 +447,57 @@
"domain_dns_registrar_experimental": "これまでのところ、**{registrar}**のAPIとのインターフェースは、YunoHostコミュニティによって適切にテストおよびレビューされていません。サポートは**非常に実験的**です-注意してください!", "domain_dns_registrar_experimental": "これまでのところ、**{registrar}**のAPIとのインターフェースは、YunoHostコミュニティによって適切にテストおよびレビューされていません。サポートは**非常に実験的**です-注意してください!",
"domain_dns_registrar_managed_in_parent_domain": "このドメインは{parent_domain_link}のサブドメインです。DNS レジストラーの構成は、{parent_domain}の設定パネルで管理する必要があります。", "domain_dns_registrar_managed_in_parent_domain": "このドメインは{parent_domain_link}のサブドメインです。DNS レジストラーの構成は、{parent_domain}の設定パネルで管理する必要があります。",
"domain_dns_registrar_not_supported": "YunoHost は、このドメインを処理するレジストラを自動的に検出できませんでした。DNS レコードは、https://yunohost.org/dns のドキュメントに従って手動で構成する必要があります。", "domain_dns_registrar_not_supported": "YunoHost は、このドメインを処理するレジストラを自動的に検出できませんでした。DNS レコードは、https://yunohost.org/dns のドキュメントに従って手動で構成する必要があります。",
"domain_dns_registrar_supported": "YunoHost は、このドメインがレジストラ**{registrar}**によって処理されていることを自動的に検出しました。必要に応じて適切なAPI資格情報を提供すると、YunoHostはこのDNSゾーンを自動的に構成します。API 資格情報の取得方法に関するドキュメントは、https://yunohost.org/registar_api_{registrar} ページにあります。(https://yunohost.org/dns のドキュメントに従ってDNSレコードを手動で構成することもできます)", "domain_dns_registrar_supported": "YunoHost は、このドメインがレジストラ **{registrar}** によって処理されていることを自動的に検出しました。必要に応じて適切なAPI資格情報を提供すると、YunoHostはこのDNSゾーンを自動的に構成します。API 資格情報の取得方法に関するドキュメントは、https://yunohost.org/registar_api_{registrar} ページにあります。(https://yunohost.org/dns のドキュメントに従ってDNSレコードを手動で構成することもできます)",
"domain_dns_registrar_yunohost": "このドメインは nohost.me / nohost.st / ynh.fr であるため、そのDNS構成は、それ以上の構成なしでYunoHostによって自動的に処理されます。(「YunoHost Dyndns Update」コマンドを参照)", "domain_dns_registrar_yunohost": "このドメインは nohost.me / nohost.st / ynh.fr であるため、DNS構成は特別な構成なしでYunoHostによって自動的に処理されます。(yunohost dyndns update コマンドを参照)",
"domain_dyndns_root_unknown": "'{domain}' ドメインのルートを '{name}' にリダイレクト", "domain_dyndns_root_unknown": "不明な DynDNS ルートドメイン",
"domain_exists": "この名前のバックアップアーカイブはすでに存在します", "domain_exists": "この名前のバックアップアーカイブはすでに存在します",
"domain_hostname_failed": "新しいホスト名を設定できません。これにより、後で問題が発生する可能性があります(問題ない可能性あります)。", "domain_hostname_failed": "新しいホスト名を設定できません。これにより、後で問題が発生する可能性があります(問題ない可能性あります)。",
"domain_registrar_is_not_configured": "レジストラーは、ドメイン {domain} 用にまだ構成されていません。", "domain_registrar_is_not_configured": "レジストラーは、ドメイン {domain} 用にまだ構成されていません。",
"domain_remove_confirm_apps_removal": "このドメインを削除すると、これらのアプリケーションが削除されます。\n{apps}\n\nよろしいですか?[{answers}]", "domain_remove_confirm_apps_removal": "このドメインを削除すると、これらのアプリケーションが削除されます。\n{apps}\n\nよろしいですか? [{answers}]",
"domain_uninstall_app_first": "これらのアプリケーションは、ドメインに引き続きインストールされます。\n{apps}\n\nドメインの削除に進む前に、「yunohostアプリ削除the_app_id」を使用してアンインストールするか、「yunohostアプリ変更URL the_app_id」を使用して別のドメインに移動してください。", "domain_uninstall_app_first": "これらのアプリケーションは、ドメインにインストールされたままです。\n{apps}\n\nドメインの削除に進む前に、yunohost app remove <the_app_id> を実行してアンインストールするか、yunohost app change-url <the_app_id> を実行してアプリケーションを別のドメインに移動してください",
"domain_unknown": "ドメイン {domain}を作成できません: {error}", "domain_unknown": "ドメイン '{domain}' は不明です",
"domains_available": "ドメイン管理", "domains_available": "利用可能なドメイン:",
"done": "完了", "done": "完了",
"downloading": "ダウンロード中...", "downloading": "ダウンロード中...",
"dpkg_is_broken": "dpkg / APT(システムパッケージマネージャー)が壊れた状態にあるように見えるため、現在はこれを行うことができません...SSH経由で接続し、 'sudo apt install --fix-broken'および/または 'sudo dpkg --configure -a'および/または 'sudo dpkg --audit'を実行することで、この問題を解決しようとすることができます。", "dpkg_is_broken": "dpkg / APT(システムパッケージマネージャー)が壊れた状態にあるように見えるため、現在はこれを行うことができません... SSH経由で接続し、 'sudo apt install --fix-broken' および/または 'sudo dpkg --configure -a' および/または 'sudo dpkg --audit' を実行することで、この問題を解決できるかもしれません。",
"dpkg_lock_not_available": "別のプログラムがdpkg(システムパッケージマネージャー)のロックを使用しているように見えるため、このコマンドは現在実行できません", "dpkg_lock_not_available": "別のプログラムがdpkg(システムパッケージマネージャー)のロックを使用しているように見えるため、このコマンドは現在実行できません",
"dyndns_could_not_check_available": "{domain}{provider}で利用できるかどうかを確認できませんでした。", "dyndns_could_not_check_available": "{domain}{provider}で利用できるかどうかを確認できませんでした。",
"dyndns_ip_update_failed": "IP アドレスを DynDNS 更新できませんでした", "dyndns_ip_update_failed": "IP アドレスを DynDNS 更新できませんでした",
"dyndns_ip_updated": "DynDNSでIPを更新しました", "dyndns_ip_updated": "DynDNSでIPを更新しました",
"dyndns_no_domain_registered": "このカテゴリーにログが登録されていません", "dyndns_no_domain_registered": "DynDNS に登録されているドメインがありません",
"dyndns_provider_unreachable": "DynDNSプロバイダー{provider}に到達できません:YunoHostがインターネットに正しく接続されていないか、ダイネットサーバーがダウンしています。", "dyndns_provider_unreachable": "DynDNSプロバイダー {provider} に到達できません: YunoHostがインターネットに正しく接続されていないか、dynetteサーバーがダウンしています。",
"dyndns_registered": "このカテゴリーにログが登録されていません", "dyndns_registered": "登録されている DynDNS ドメイン",
"dyndns_registration_failed": "DynDNS ドメインを登録できませんでした: {error}", "dyndns_registration_failed": "DynDNS ドメインを登録できませんでした: {error}",
"dyndns_unavailable": "ドメイン {domain}を作成できません: {error}", "dyndns_unavailable": "ドメイン '{domain}' は使用できません。",
"dyndns_domain_not_provided": "DynDNS プロバイダー{provider}ドメイン{domain}を提供できません。", "dyndns_domain_not_provided": "DynDNS プロバイダー{provider}ドメイン{domain}を提供できません。",
"extracting": "抽出。。。", "extracting": "抽出中…",
"field_invalid": "フィールドは必要です。", "field_invalid": "無効なフィールド '{}'",
"file_does_not_exist": "ファイル {path}が存在しません。", "file_does_not_exist": "ファイル {path}が存在しません。",
"firewall_reloaded": "ファイアウォールがリロードされました", "firewall_reloaded": "ファイアウォールがリロードされました",
"firewall_rules_cmd_failed": "一部のファイアウォール規則コマンドが失敗しました。ログの詳細情報。", "firewall_rules_cmd_failed": "一部のファイアウォール ルール コマンドが失敗しました。詳細情報はログに残されています。",
"global_settings_reset_success": "グローバルIP: <code>{global}</code>", "global_settings_reset_success": "グローバル設定をリセットする",
"global_settings_setting_admin_strength": "管理者パスワードの強度要件", "global_settings_setting_admin_strength": "管理者パスワードの強度要件",
"global_settings_setting_admin_strength_help": "これらの要件は、パスワードを初期化または変更する場合にのみ適用されます", "global_settings_setting_admin_strength_help": "これらの要件は、パスワードを初期化または変更する場合にのみ適用されます",
"global_settings_setting_backup_compress_tar_archives": "バックアップの圧縮", "global_settings_setting_backup_compress_tar_archives": "バックアップの圧縮",
"global_settings_setting_backup_compress_tar_archives_help": "新しいバックアップを作成するとき、圧縮されていないアーカイブ (.tar) ではなく、アーカイブを圧縮 (.tar.gz) します。注意:このオプションを有効にすると、バックアップアーカイブの作成が軽くなりますが、最初のバックアップ手順が大幅に長くなり、CPUに負担がかかります。", "global_settings_setting_backup_compress_tar_archives_help": "新しいバックアップを作成するとき、圧縮されていないアーカイブ (.tar) ではなく、アーカイブを圧縮 (.tar.gz) します。注意: このオプションを有効にすると、バックアップアーカイブの容量は小さくなりますが、最初のバックアップ処理が大幅に長くなり、CPUに負担がかかります。",
"global_settings_setting_dns_exposure": "DNS の構成と診断で考慮すべき IP バージョン", "global_settings_setting_dns_exposure": "DNS の構成と診断で考慮すべき IP バージョン",
"global_settings_setting_dns_exposure_help": "注意:これは、推奨されるDNS構成と診断チェックにのみ影響します。これはシステム構成には影響しません。", "global_settings_setting_dns_exposure_help": "注意: これは、推奨されるDNS構成と診断チェックにのみ影響します。これはシステム構成には影響しません。",
"global_settings_setting_nginx_compatibility": "NGINXの互換性", "global_settings_setting_nginx_compatibility": "NGINXの互換性",
"global_settings_setting_nginx_compatibility_help": "WebサーバーNGINXの互換性とセキュリティのトレードオフ。暗号(およびその他のセキュリティ関連の側面)に影響します", "global_settings_setting_nginx_compatibility_help": "WebサーバーNGINXの互換性とセキュリティの間にはトレードオフがあります。これは暗号(およびその他のセキュリティ関連の側面)に影響します",
"global_settings_setting_nginx_redirect_to_https": "HTTPSを強制", "global_settings_setting_nginx_redirect_to_https": "HTTPSを強制",
"global_settings_setting_nginx_redirect_to_https_help": "デフォルトでHTTPリクエストをHTTPにリダイレクトします(あなたが何をしているのか本当にわからない限り、オフにしないでください!", "global_settings_setting_nginx_redirect_to_https_help": "デフォルトでHTTPリクエストをHTTPにリダイレクトします(あなたが何をしているのか本当に本当にわかっていると自信を持てないのであれば、オフにしないでください!)",
"global_settings_setting_passwordless_sudo": "管理者がパスワードを再入力せずに「sudo」を使用できるようにする", "global_settings_setting_passwordless_sudo": "管理者がパスワードを再入力せずに'sudo'を使用できるようにする",
"global_settings_setting_portal_theme_help": "カスタム ポータル テーマの作成の詳細については、https://yunohost.org/theming を参照してください", "global_settings_setting_portal_theme_help": "カスタム ポータル テーマの作成の詳細については、https://yunohost.org/theming を参照してください",
"global_settings_setting_postfix_compatibility": "後置の互換性", "global_settings_setting_postfix_compatibility": "Postfixの互換性",
"global_settings_setting_pop3_enabled": "POP3 を有効にする", "global_settings_setting_pop3_enabled": "POP3 を有効にする",
"global_settings_setting_pop3_enabled_help": "メール サーバーの POP3 プロトコルを有効にする", "global_settings_setting_pop3_enabled_help": "メール サーバーの POP3 プロトコルを有効にする",
"global_settings_setting_portal_theme": "ユーザーポータルでタイルに表示する", "global_settings_setting_portal_theme": "ポータルのテーマ",
"global_settings_setting_root_access_explain": "Linux システムでは、「ルート」が絶対管理者です。YunoHost のコンテキストでは、サーバーのローカルネットワークからを除き、直接の「ルート」SSH ログインはデフォルトで無効になっています。'admins' グループのメンバーは、sudo コマンドを使用して、コマンドラインから root として動作できます。ただし、何らかの理由で通常の管理者がログインできなくなった場合に、システムをデバッグするための(堅牢な)rootパスワードがあると便利です。", "global_settings_setting_root_access_explain": "Linux システムでは'root'が絶対に管理者です。YunoHost のコンテキストでは、'root'ユーザーでのSSH ログインは(サーバーのローカルネットワークからのSSHである場合を除き)デフォルトで無効になっています。'admins' グループのメンバーは、sudo コマンドを使用することで、root としてコマンドを実行できます。ただし、何らかの理由で通常の管理者がログインできなくなった場合に、システムをデバッグするための(堅牢な)rootパスワードがあると便利です。",
"global_settings_setting_security_experimental_enabled": "実験的なセキュリティ機能", "global_settings_setting_security_experimental_enabled": "実験的なセキュリティ機能",
"global_settings_setting_security_experimental_enabled_help": "実験的なセキュリティ機能を有効にします(何をしているのかわからない場合は有効にしないでください)", "global_settings_setting_security_experimental_enabled_help": "実験的なセキュリティ機能を有効にします(何をしているのかわからない場合は有効にしないでください)",
"global_settings_setting_smtp_allow_ipv6_help": "IPv6 を使用したメールの送受信を許可する", "global_settings_setting_smtp_allow_ipv6_help": "IPv6 を使用したメールの送受信を許可する",
"global_settings_setting_smtp_relay_enabled": "SMTP リレーを有効にする", "global_settings_setting_smtp_relay_enabled": "SMTP リレーを有効にする",
"global_settings_setting_smtp_relay_enabled_help": "この yunohost インスタンスの代わりにメールを送信するために使用する SMTP リレーを有効にします。このような状況のいずれかにある場合に便利です:25ポートがISPまたはVPSプロバイダーによってブロックされている、DUHLにリストされている住宅用IPがある、逆引きDNSを構成できない、またはこのサーバーがインターネットに直接公開されておらず、他のものを使用してメールを送信したい。", "global_settings_setting_smtp_relay_enabled_help": "SMTP リレーを有効にすることで、この yunohost サーバー以外の\nサーバーが(代わりに)メールを送信するようになります。この設定は次の状態にある場合に便利です: 25ポートがISPまたはVPSプロバイダーによってブロックされている / DUHLリスト(電子メール拒否リスト)にお住まいのIPが登録されている / 逆引きDNSを構成できない / このサーバーがインターネットに直接公開されておらず、他のサーバーを使用してメールを送信したい。",
"global_settings_setting_smtp_relay_host": "SMTP リレー ホスト", "global_settings_setting_smtp_relay_host": "SMTP リレー ホスト",
"global_settings_setting_smtp_relay_password": "SMTP リレー パスワード", "global_settings_setting_smtp_relay_password": "SMTP リレー パスワード",
"global_settings_setting_smtp_relay_port": "SMTP リレー ポート", "global_settings_setting_smtp_relay_port": "SMTP リレー ポート",
@ -507,7 +507,7 @@
"global_settings_setting_ssh_password_authentication": "パスワード認証", "global_settings_setting_ssh_password_authentication": "パスワード認証",
"global_settings_setting_ssh_password_authentication_help": "SSH のパスワード認証を許可する", "global_settings_setting_ssh_password_authentication_help": "SSH のパスワード認証を許可する",
"global_settings_setting_ssh_port": "SSH ポート", "global_settings_setting_ssh_port": "SSH ポート",
"global_settings_setting_ssowat_panel_overlay_enabled": "アプリで小さな「YunoHost」ポータルショートカットの正方形を有効にします", "global_settings_setting_ssowat_panel_overlay_enabled": "アプリで小さな'YunoHost'ポータルショートカットの正方形を有効にします",
"global_settings_setting_user_strength": "ユーザー パスワードの強度要件", "global_settings_setting_user_strength": "ユーザー パスワードの強度要件",
"global_settings_setting_webadmin_allowlist_help": "ウェブ管理者へのアクセスを許可されたIPアドレス。", "global_settings_setting_webadmin_allowlist_help": "ウェブ管理者へのアクセスを許可されたIPアドレス。",
"global_settings_setting_webadmin_allowlist": "ウェブ管理者 IP 許可リスト", "global_settings_setting_webadmin_allowlist": "ウェブ管理者 IP 許可リスト",
@ -522,7 +522,7 @@
"invalid_shell": "無効なシェル: {shell}", "invalid_shell": "無効なシェル: {shell}",
"ip6tables_unavailable": "ここではip6tablesを使うことはできません。あなたはコンテナ内にいるか、カーネルがサポートしていません", "ip6tables_unavailable": "ここではip6tablesを使うことはできません。あなたはコンテナ内にいるか、カーネルがサポートしていません",
"group_cannot_edit_primary_group": "グループ '{group}' を手動で編集することはできません。これは、特定のユーザーを 1 人だけ含むためのプライマリ グループです。", "group_cannot_edit_primary_group": "グループ '{group}' を手動で編集することはできません。これは、特定のユーザーを 1 人だけ含むためのプライマリ グループです。",
"group_cannot_edit_visitors": "グループの「訪問者」を手動で編集することはできません。匿名の訪問者を代表する特別なグループです", "group_cannot_edit_visitors": "グループの'訪問者'を手動で編集することはできません。匿名の訪問者を代表する特別なグループです",
"group_creation_failed": "グループ '{group}' を作成できませんでした: {error}", "group_creation_failed": "グループ '{group}' を作成できませんでした: {error}",
"group_deleted": "グループ '{group}' が削除されました", "group_deleted": "グループ '{group}' が削除されました",
"group_deletion_failed": "グループ '{group}' を削除できませんでした: {error}", "group_deletion_failed": "グループ '{group}' を削除できませんでした: {error}",
@ -547,24 +547,24 @@
"log_app_change_url": "{} アプリのアクセスURLを変更", "log_app_change_url": "{} アプリのアクセスURLを変更",
"log_app_config_set": "{} アプリに設定を適用する", "log_app_config_set": "{} アプリに設定を適用する",
"log_app_makedefault": "{} をデフォルトのアプリにする", "log_app_makedefault": "{} をデフォルトのアプリにする",
"log_app_remove": "「{}」アプリを削除する", "log_app_remove": "'{}'アプリを削除する",
"log_app_upgrade": "「{}」アプリをアップグレードする", "log_app_upgrade": "アプリ '{app}' をアップグレードする",
"log_available_on_yunopaste": "このログは、{url}", "log_available_on_yunopaste": "このログは、{url}",
"log_backup_create": "バックアップアーカイブを作成する", "log_backup_create": "バックアップ作成できませんでした",
"log_backup_restore_app": "バックアップを復元する {name}", "log_backup_restore_app": "バックアップアーカイブから'{}'を復元する",
"log_backup_restore_system": "収集したファイルからバックアップアーカイブを作成しています...", "log_backup_restore_system": "バックアップアーカイブからシステムを復元する",
"log_corrupted_md_file": "ログに関連付けられている YAML メタデータ ファイルが破損しています: '{md_file}\nエラー: {error}'", "log_corrupted_md_file": "ログに関連付けられている YAML メタデータ ファイルが破損しています: '{md_file}\nエラー: {error}'",
"log_does_exists": "「{log}」という名前の操作ログはありません。「yunohostログリスト」を使用して、利用可能なすべての操作ログを表示します", "log_does_exists": "'{log}'という名前の操作ログはありません。'yunohostログリスト'を使用して、利用可能なすべての操作ログを表示します",
"log_domain_add": "ドメイン {name}追加する", "log_domain_add": "'{}'ドメインをシステム構成に追加する",
"log_domain_config_set": "ドメイン '{}' の構成を更新する", "log_domain_config_set": "ドメイン '{}' の構成を更新する",
"log_domain_dns_push": "{name} DNSレコードを登録する", "log_domain_dns_push": "ドメイン '{}' の DNS レコードをプッシュする",
"log_domain_main_domain": "「{}」をメインドメインにする", "log_domain_main_domain": "'{}'をメインドメインにする",
"log_domain_remove": "システム構成から「{}」ドメインを削除する", "log_domain_remove": "システム構成から'{}'ドメインを削除する",
"log_dyndns_subscribe": "YunoHostコアのアップグレードを開始しています...", "log_dyndns_subscribe": "YunoHostサブドメイン'{}'を購読する",
"log_dyndns_update": "YunoHostサブドメイン「{}」に関連付けられているIPを更新します", "log_dyndns_update": "YunoHostサブドメイン'{}'に関連付けられているIPを更新します",
"log_help_to_get_failed_log": "操作 '{desc}' を完了できませんでした。ヘルプを取得するには、「yunohostログ共有{name}」コマンドを使用してこの操作の完全なログを共有してください", "log_help_to_get_failed_log": "操作 '{desc}' を完了できませんでした。ヘルプを取得するには、'yunohostログ共有{name}'コマンドを使用してこの操作の完全なログを共有してください",
"log_help_to_get_log": "操作「{desc}」のログを表示するには、「yunohostログショー{name}」コマンドを使用します。", "log_help_to_get_log": "操作'{desc}'のログを表示するには、'yunohostログショー{name}'コマンドを使用します。",
"log_letsencrypt_cert_install": "「{}」ドメインにLet's Encrypt証明書をインストールする", "log_letsencrypt_cert_install": "'{}'ドメインにLet's Encrypt証明書をインストールする",
"log_letsencrypt_cert_renew": "Lets Encrypt証明書を更新する", "log_letsencrypt_cert_renew": "Lets Encrypt証明書を更新する",
"log_link_to_failed_log": "操作 '{desc}' を完了できませんでした。ヘルプを取得するには、 <a href=\"#/tools/logs/{name}\">ここをクリックして</a> この操作の完全なログを提供してください", "log_link_to_failed_log": "操作 '{desc}' を完了できませんでした。ヘルプを取得するには、 <a href=\"#/tools/logs/{name}\">ここをクリックして</a> この操作の完全なログを提供してください",
"log_link_to_log": "この操作の完全なログ: ''<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\">{desc}</a>", "log_link_to_log": "この操作の完全なログ: ''<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\">{desc}</a>",
@ -572,13 +572,13 @@
"log_permission_create": "作成権限 '{}'", "log_permission_create": "作成権限 '{}'",
"log_permission_delete": "削除権限 '{}'", "log_permission_delete": "削除権限 '{}'",
"log_permission_url": "権限 '{}' に関連する URL を更新する", "log_permission_url": "権限 '{}' に関連する URL を更新する",
"log_regen_conf": "システム設定", "log_regen_conf": "システム構成 '{}' を再生成する",
"log_remove_on_failed_install": "インストールに失敗した後に「{}」を削除します", "log_remove_on_failed_install": "インストールに失敗した後に'{}'を削除します",
"log_resource_snippet": "リソースのプロビジョニング/プロビジョニング解除/更新", "log_resource_snippet": "リソースのプロビジョニング/プロビジョニング解除/更新",
"log_selfsigned_cert_install": "「{}」ドメインに自己署名証明書をインストールする", "log_selfsigned_cert_install": "'{}'ドメインに自己署名証明書をインストールする",
"log_user_create": "「{}」ユーザーを追加する", "log_user_create": "{} ユーザーを追加",
"log_user_delete": "「{}」ユーザーの削除", "log_user_delete": "{} ユーザーを削除",
"log_user_group_create": "「{}」グループの作成", "log_user_group_create": "{} グループを作成",
"log_settings_reset": "設定をリセット", "log_settings_reset": "設定をリセット",
"log_settings_reset_all": "すべての設定をリセット", "log_settings_reset_all": "すべての設定をリセット",
"log_settings_set": "設定を適用", "log_settings_set": "設定を適用",
@ -587,9 +587,9 @@
"log_tools_reboot": "サーバーを再起動", "log_tools_reboot": "サーバーを再起動",
"log_tools_shutdown": "サーバーをシャットダウン", "log_tools_shutdown": "サーバーをシャットダウン",
"log_tools_upgrade": "システムパッケージのアップグレード", "log_tools_upgrade": "システムパッケージのアップグレード",
"log_user_group_delete": "「{}」グループの削除", "log_user_group_delete": "{} グループを削除",
"log_user_group_update": "'{}' グループを更新", "log_user_group_update": "{} グループを更新",
"log_user_import": "ユーザーインポート", "log_user_import": "ユーザーインポート",
"mailbox_used_space_dovecot_down": "使用済みメールボックススペースをフェッチする場合は、Dovecotメールボックスサービスが稼働している必要があります", "mailbox_used_space_dovecot_down": "使用済みメールボックススペースをフェッチする場合は、Dovecotメールボックスサービスが稼働している必要があります",
"log_user_permission_reset": "アクセス許可 '{}' をリセットします", "log_user_permission_reset": "アクセス許可 '{}' をリセットします",
"mailbox_disabled": "ユーザーの{user}に対して電子メールがオフになっている", "mailbox_disabled": "ユーザーの{user}に対して電子メールがオフになっている",
@ -600,25 +600,25 @@
"migration_0021_main_upgrade": "メインアップグレードを開始しています...", "migration_0021_main_upgrade": "メインアップグレードを開始しています...",
"migration_0021_not_enough_free_space": "/var/の空き容量はかなり少ないです!この移行を実行するには、少なくとも 1 GB の空き容量が必要です。", "migration_0021_not_enough_free_space": "/var/の空き容量はかなり少ないです!この移行を実行するには、少なくとも 1 GB の空き容量が必要です。",
"migration_0021_modified_files": "次のファイルは手動で変更されていることが判明し、アップグレード後に上書きされる可能性があることに注意してください: {manually_modified_files}", "migration_0021_modified_files": "次のファイルは手動で変更されていることが判明し、アップグレード後に上書きされる可能性があることに注意してください: {manually_modified_files}",
"migration_0021_not_buster2": "現在の Debian ディストリビューションは Buster ではありません!すでにBuster->Bullseyeの移行を実行している場合、このエラーは移行手順が100% s成功しなかったという事実の兆候です(そうでなければ、YunoHostは完了のフラグを立てます)。Webadminのツール>ログにある移行の**完全な**ログを必要とするサポートチームで何が起こったのかを調査することをお勧めします。", "migration_0021_not_buster2": "現在の Debian ディストリビューションは Buster ではありません! すでにBuster->Bullseyeの移行を実行している場合、このエラーは移行手順が100% 完璧に成功しなかったという事実を意味します(そうでなければ、YunoHostは完了のフラグを立てます)。Web管理画面のツール>ログにある移行の**完全な**ログを取得し、サポートチームと共に何が起こったのか調査することをお勧めします。",
"migration_0021_patch_yunohost_conflicts": "競合の問題を回避するためにパッチを適用しています...", "migration_0021_patch_yunohost_conflicts": "競合の問題を回避するためにパッチを適用しています...",
"migration_0021_patching_sources_list": "sources.listsにパッチを適用しています...", "migration_0021_patching_sources_list": "sources.listsにパッチを適用しています...",
"migration_0021_problematic_apps_warning": "以下の問題のあるインストール済みアプリが検出されました。これらはYunoHostアプリカタログからインストールされていないか、「working」としてフラグが立てられていないようです。したがって、アップグレード後も動作することを保証することはできません: {problematic_apps}", "migration_0021_problematic_apps_warning": "以下の問題のあるインストール済みアプリが検出されました。これらはYunoHostアプリカタログからインストールされていないか、'working'としてフラグが立てられていないようです。したがって、アップグレード後も動作することを保証することはできません: {problematic_apps}",
"migration_0021_still_on_buster_after_main_upgrade": "メインのアップグレード中に問題が発生しましたが、システムはまだDebian Busterです", "migration_0021_still_on_buster_after_main_upgrade": "メインのアップグレード中に問題が発生しましたが、システムはまだDebian Busterです",
"migration_0021_system_not_fully_up_to_date": "システムが完全に最新ではありません。Bullseyeへの移行を実行する前に、まずは通常のアップグレードを実行してください。", "migration_0021_system_not_fully_up_to_date": "システムが完全に最新ではありません。Bullseyeへの移行を実行する前に、まずは通常のアップグレードを実行してください。",
"migration_0023_not_enough_space": "移行を実行するのに十分な領域を {path} で使用できるようにします。", "migration_0023_not_enough_space": "移行を実行するのに十分な領域を {path} で使用できるようにします。",
"migration_0023_postgresql_11_not_installed": "PostgreSQL がシステムにインストールされていません。何もすることはありません。", "migration_0023_postgresql_11_not_installed": "PostgreSQL がシステムにインストールされていません。何もすることはありません。",
"migration_0023_postgresql_13_not_installed": "PostgreSQL 11はインストールされていますが、PostgreSQL 13はインストールされてい!?:(システムで何か奇妙なことが起こった可能性があります...", "migration_0023_postgresql_13_not_installed": "PostgreSQL 11はインストールされていますが、PostgreSQL 13はインストールされてい!?:(システムで何か奇妙なことが起こった可能性があります...",
"migration_0024_rebuild_python_venv_broken_app": "このアプリ用にvirtualenvを簡単に再構築できないため、{app}スキップします。代わりに、「yunohostアプリのアップグレード-{app}を強制」を使用してこのアプリを強制的にアップグレードして、状況を修正する必要があります。", "migration_0024_rebuild_python_venv_broken_app": "このアプリ用にvirtualenvを簡単に再構築できないため、{app}スキップします。代わりに、'yunohostアプリのアップグレード-{app}を強制'を使用してこのアプリを強制的にアップグレードして、状況を修正する必要があります。",
"migration_0024_rebuild_python_venv_disclaimer_base": "Debian Bullseye へのアップグレード後、Debian に同梱されている新しい Python バージョンに変換するために、いくつかの Python アプリケーションを部分的に再構築する必要があります (技術的には、「virtualenv」と呼ばれるものを再作成する必要があります)。それまでの間、これらのPythonアプリケーションは機能しない可能性があります。YunoHostは、以下に詳述するように、それらのいくつかについて仮想環境の再構築を試みることができます。他のアプリの場合、または再構築の試行が失敗した場合は、それらのアプリのアップグレードを手動で強制する必要があります。", "migration_0024_rebuild_python_venv_disclaimer_base": "Debian Bullseye へのアップグレード後、Debian に同梱されている新しい Python バージョンに変換するために、いくつかの Python アプリケーションを部分的に再構築する必要があります (技術的には、'virtualenv'と呼ばれるものを再作成する必要があります)。それまでの間、これらのPythonアプリケーションは機能しない可能性があります。YunoHostは、以下に詳述するように、それらのいくつかについて仮想環境の再構築を試みることができます。他のアプリの場合、または再構築の試行が失敗した場合は、それらのアプリのアップグレードを手動で強制する必要があります。",
"migration_0024_rebuild_python_venv_disclaimer_ignored": "これらのアプリに対して Virtualenvs を自動的に再構築することはできません。あなたはそれらのアップグレードを強制する必要があります、それはコマンドラインから行うことができます: 'yunohostアプリのアップグレード - -force APP':{ignored_apps}", "migration_0024_rebuild_python_venv_disclaimer_ignored": "これらのアプリに対して Virtualenvs を自動的に再構築することはできません。あなたはそれらのアップグレードを強制する必要があります、それはコマンドラインから行うことができます: 'yunohostアプリのアップグレード - -force APP':{ignored_apps}",
"migration_0024_rebuild_python_venv_disclaimer_rebuild": "virtualenvの再構築は、次のアプリに対して試行されます(注意:操作には時間がかかる場合があります)。 {rebuild_apps}", "migration_0024_rebuild_python_venv_disclaimer_rebuild": "virtualenvの再構築は、次のアプリに対して試行されます(注意:操作には時間がかかる場合があります)。 {rebuild_apps}",
"migration_0024_rebuild_python_venv_failed": "{app} の Python virtualenv の再構築に失敗しました。これが解決されない限り、アプリは機能しない場合があります。「yunohostアプリのアップグレード--強制{app}」を使用してこのアプリのアップグレードを強制して、状況を修正する必要があります。", "migration_0024_rebuild_python_venv_failed": "{app} の Python virtualenv の再構築に失敗しました。これが解決されない限り、アプリは機能しない場合があります。'yunohostアプリのアップグレード--強制{app}'を使用してこのアプリのアップグレードを強制して、状況を修正する必要があります。",
"migration_0024_rebuild_python_venv_in_progress": "現在、 '{app}'のPython仮想環境を再構築しようとしています", "migration_0024_rebuild_python_venv_in_progress": "現在、 '{app}'のPython仮想環境を再構築しようとしています",
"migration_description_0021_migrate_to_bullseye": "システムを Debian ブルズアイと YunoHost 11.x にアップグレードする", "migration_description_0021_migrate_to_bullseye": "システムを Debian Bullseyeと YunoHost 11.x にアップグレードする",
"migration_description_0022_php73_to_php74_pools": "php7.3-fpm 'pool' conf ファイルを php7.4 に移行します", "migration_description_0022_php73_to_php74_pools": "php7.3-fpm 'pool' conf ファイルを php7.4 に移行します",
"migration_description_0023_postgresql_11_to_13": "PostgreSQL 11 から 13 へのデータベースの移行", "migration_description_0023_postgresql_11_to_13": "PostgreSQL 11 から 13 へのデータベースの移行",
"migration_description_0024_rebuild_python_venv": "ブルズアイ移行後にPythonアプリを修復する", "migration_description_0024_rebuild_python_venv": "Bullseye移行後にPythonアプリを修復する",
"migration_description_0025_global_settings_to_configpanel": "従来のグローバル設定の命名法を新しい最新の命名法に移行する", "migration_description_0025_global_settings_to_configpanel": "従来のグローバル設定の命名法を新しい最新の命名法に移行する",
"migration_ldap_rollback_success": "システムがロールバックされました。", "migration_ldap_rollback_success": "システムがロールバックされました。",
"migrations_already_ran": "これらの移行は既に完了しています: {ids}", "migrations_already_ran": "これらの移行は既に完了しています: {ids}",
@ -633,24 +633,24 @@
"migrations_running_forward": "移行{id}を実行しています...", "migrations_running_forward": "移行{id}を実行しています...",
"migrations_skip_migration": "移行{id}スキップしています...", "migrations_skip_migration": "移行{id}スキップしています...",
"migrations_success_forward": "移行{id}完了しました", "migrations_success_forward": "移行{id}完了しました",
"migrations_to_be_ran_manually": "移行{id}は手動で実行する必要があります。ウェブ管理ページの移行→ツールに移動するか、「yunohostツールの移行実行」を実行してください。", "migrations_to_be_ran_manually": "移行{id}は手動で実行する必要があります。Web管理ページの移行→ツールに移動するか、'yunohost tools migrations run'を実行してください。",
"not_enough_disk_space": "'{path}'に十分な空き容量がありません", "not_enough_disk_space": "'{path}'に十分な空き容量がありません",
"operation_interrupted": "操作は手動で中断されたようですね?", "operation_interrupted": "操作は手動で中断されたようですね?",
"migrations_no_migrations_to_run": "実行する移行はありません", "migrations_no_migrations_to_run": "実行する移行はありません",
"migrations_no_such_migration": "「{id}」と呼ばれる移行はありません", "migrations_no_such_migration": "'{id}'と呼ばれる移行はありません",
"other_available_options": "...および{n}個の表示されない他の使用可能なオプション", "other_available_options": "...および{n}個の表示されない他の使用可能なオプション",
"migrations_not_pending_cant_skip": "これらの移行は保留中ではないため、スキップすることはできません。 {ids}", "migrations_not_pending_cant_skip": "これらの移行は保留中ではないため、スキップすることはできません。 {ids}",
"migrations_pending_cant_rerun": "これらの移行はまだ保留中であるため、再度実行することはできません{ids}", "migrations_pending_cant_rerun": "これらの移行はまだ保留中であるため、再度実行することはできません{ids}",
"password_confirmation_not_the_same": "パスワードが一致しません", "password_confirmation_not_the_same": "パスワードが一致しません",
"password_listed": "このパスワードは、世界で最も使用されているパスワードの1つです。もっとユニークなものを選んでください。", "password_listed": "このパスワードは、世界で最も使用されているパスワードの1つです。もっと他の人と被っていないものを選んでください。",
"password_too_long": "127文字未満のパスワードを選択してください", "password_too_long": "127文字未満のパスワードを使用してください",
"password_too_simple_2": "パスワードは8文字以上で、数字、大文字、小文字を含める必要があります", "password_too_simple_2": "パスワードは8文字以上で、数字、大文字、小文字を含める必要があります",
"password_too_simple_3": "パスワードは8文字以上で、数字、大文字、小文字、特殊文字を含める必要があります", "password_too_simple_3": "パスワードは8文字以上で、数字、大文字、小文字、特殊文字を含める必要があります",
"password_too_simple_4": "パスワードは12文字以上で、数字、大文字、小文字、特殊文字を含める必要があります", "password_too_simple_4": "パスワードは12文字以上で、数字、大文字、小文字、特殊文字を含める必要があります",
"pattern_backup_archive_name": "最大 30 文字、英数字、-_ を含む有効なファイル名である必要があります。文字のみ", "pattern_backup_archive_name": "有効なファイル名は最大 30 文字、英数字、-_. のみで構成されたものである必要があります。",
"pattern_domain": "有効なドメイン名である必要があります(例:my-domain.org)", "pattern_domain": "有効なドメイン名である必要があります(例:my-domain.org)",
"pattern_email": "「+」記号のない有効な電子メールアドレスである必要があります(例:someone@example.com)", "pattern_email": "'+'記号のない有効な電子メールアドレスである必要があります(例:someone@example.com)",
"pattern_email_forward": "有効な電子メールアドレスである必要があり、「+」記号が受け入れられます(例:someone+tag@example.com)", "pattern_email_forward": "有効な電子メールアドレスである必要があり、'+'記号が受け入れられます(例:someone+tag@example.com)",
"pattern_firstname": "有効な名前(3 文字以上)である必要があります。", "pattern_firstname": "有効な名前(3 文字以上)である必要があります。",
"pattern_fullname": "有効なフルネーム (3 文字以上) である必要があります。", "pattern_fullname": "有効なフルネーム (3 文字以上) である必要があります。",
"pattern_lastname": "有効な姓 (3 文字以上) である必要があります。", "pattern_lastname": "有効な姓 (3 文字以上) である必要があります。",
@ -667,7 +667,7 @@
"permission_cant_add_to_all_users": "権限{permission}すべてのユーザーに追加することはできません。", "permission_cant_add_to_all_users": "権限{permission}すべてのユーザーに追加することはできません。",
"permission_created": "アクセス許可 '{permission}' が作成されました", "permission_created": "アクセス許可 '{permission}' が作成されました",
"permission_creation_failed": "アクセス許可 '{permission}' を作成できませんでした: {error}", "permission_creation_failed": "アクセス許可 '{permission}' を作成できませんでした: {error}",
"permission_currently_allowed_for_all_users": "このアクセス許可は現在、他のユーザーに加えてすべてのユーザーに付与されています。「all_users」権限を削除するか、現在付与されている他のグループを削除することをお勧めします。", "permission_currently_allowed_for_all_users": "このアクセス許可は現在、他のユーザーに加えてすべてのユーザーに付与されています。'all_users'権限を削除するか、現在付与されている他のグループを削除することをお勧めします。",
"permission_deleted": "権限 '{permission}' が削除されました", "permission_deleted": "権限 '{permission}' が削除されました",
"permission_deletion_failed": "アクセス許可 '{permission}' を削除できませんでした: {error}", "permission_deletion_failed": "アクセス許可 '{permission}' を削除できませんでした: {error}",
"permission_not_found": "アクセス許可 '{permission}' が見つかりません", "permission_not_found": "アクセス許可 '{permission}' が見つかりません",
@ -687,36 +687,36 @@
"regenconf_file_remove_failed": "構成ファイル '{conf}' を削除できませんでした", "regenconf_file_remove_failed": "構成ファイル '{conf}' を削除できませんでした",
"regenconf_file_removed": "構成ファイル '{conf}' が削除されました", "regenconf_file_removed": "構成ファイル '{conf}' が削除されました",
"regenconf_file_updated": "構成ファイル '{conf}' が更新されました", "regenconf_file_updated": "構成ファイル '{conf}' が更新されました",
"regenconf_need_to_explicitly_specify_ssh": "ssh構成は手動で変更されていますが、実際に変更を適用するには、--forceでカテゴリ「ssh」を明示的に指定する必要があります。", "regenconf_need_to_explicitly_specify_ssh": "ssh構成は手動で変更されていますが、実際に変更を適用するには、--forceでカテゴリ'ssh'を明示的に指定する必要があります。",
"regenconf_now_managed_by_yunohost": "設定ファイル '{conf}' が YunoHost (カテゴリ {category}) によって管理されるようになりました。", "regenconf_now_managed_by_yunohost": "設定ファイル '{conf}' が YunoHost (カテゴリ {category}) によって管理されるようになりました。",
"regenconf_pending_applying": "カテゴリ '{category}' に保留中の構成を適用しています...", "regenconf_pending_applying": "カテゴリ '{category}' に保留中の構成を適用しています...",
"regenconf_up_to_date": "カテゴリ '{category}' の設定は既に最新です", "regenconf_up_to_date": "カテゴリ '{category}' の設定は既に最新です",
"regenconf_updated": "このカテゴリーにログが登録されていません", "regenconf_updated": "'{category}' の構成が更新されました",
"regenconf_would_be_updated": "カテゴリ '{category}' の構成が更新されているはずです。", "regenconf_would_be_updated": "カテゴリ '{category}' の構成が更新されているはずです。",
"regex_incompatible_with_tile": "パッケージャー!アクセス許可 '{permission}' show_tile が 'true' に設定されているため、正規表現 URL をメイン URL として定義できません", "regex_incompatible_with_tile": "パッケージャー!アクセス許可 '{permission}' show_tile が 'true' に設定されているため、正規表現 URL をメイン URL として定義できません",
"regex_with_only_domain": "ドメインに正規表現を使用することはできませんが、パスにのみ使用できます", "regex_with_only_domain": "ドメインに正規表現を使用することはできませんが、パスにのみ使用できます",
"registrar_infos": "レジストラ情報", "registrar_infos": "レジストラ情報",
"restore_already_installed_app": "'{name}' の {id} パネル設定をアップデートする", "restore_already_installed_app": "ID が'{app}'のアプリが既にインストールされている",
"restore_already_installed_apps": "次のアプリは既にインストールされているため復元できません。 {apps}", "restore_already_installed_apps": "次のアプリは既にインストールされているため復元できません。 {apps}",
"restore_backup_too_old": "このバックアップアーカイブは、古すぎるYunoHostバージョンからのものであるため、復元できません。", "restore_backup_too_old": "このバックアップアーカイブは、古すぎるYunoHostバージョンからのものであるため、復元できません。",
"restore_cleaning_failed": "一時復元ディレクトリをクリーンアップできませんでした", "restore_cleaning_failed": "一時復元ディレクトリをクリーンアップできませんでした",
"restore_complete": "復元が完了しました", "restore_complete": "復元が完了しました",
"restore_may_be_not_enough_disk_space": "システムに十分なスペースがないようです(空き:{free_space} B、必要なスペース:{needed_space} B、セキュリティマージン:{margin} B)", "restore_may_be_not_enough_disk_space": "システムに十分なスペースがないようです(空き:{free_space} B、必要なスペース:{needed_space} B、セキュリティマージン:{margin} B)",
"root_password_desynchronized": "管理者パスワードが変更されましたが、YunoHostはこれをrootパスワードに伝播できませんでした!", "root_password_desynchronized": "管理者パスワードが変更されましたが、YunoHostはこれをrootパスワードに反映できませんでした!",
"server_reboot_confirm": "サーバーはすぐに再起動しますが、よろしいですか?[{answers}]", "server_reboot_confirm": "サーバーはすぐに再起動しますが、よろしいですか? [{answers}]",
"server_shutdown": "サーバーがシャットダウンします", "server_shutdown": "サーバーがシャットダウンします",
"service_already_stopped": "サービス '{service}' は既に停止されています", "service_already_stopped": "サービス '{service}' は既に停止されています",
"service_cmd_exec_failed": "コマンド '{command}' を実行できませんでした", "service_cmd_exec_failed": "コマンド '{command}' を実行できませんでした",
"service_description_nginx": "サーバーでホストされているすべてのWebサイトへのアクセスを提供または提供します", "service_description_nginx": "サーバーでホストされているすべてのWebサイトへのアクセスを提供します",
"service_description_redis-server": "高速データ・アクセス、タスク・キュー、およびプログラム間の通信に使用される特殊なデータベース", "service_description_redis-server": "高速データ・アクセス、タスク・キュー、およびプログラム間の通信に使用される特殊なデータベース",
"service_description_rspamd": "スパムやその他の電子メール関連機能をフィルタリングします", "service_description_rspamd": "スパムフィルタリングやその他の電子メール関連機能",
"service_description_slapd": "ユーザー、ドメイン、関連情報を格納します", "service_description_slapd": "ユーザー、ドメイン、関連情報を格納します",
"service_description_ssh": "ターミナル経由でサーバーにリモート接続できます(SSHプロトコル)", "service_description_ssh": "ターミナル経由でサーバーにリモート接続できます(SSHプロトコル)",
"service_description_yunohost-api": "YunoHostウェブインターフェイスとシステム間の相互作用を管理します", "service_description_yunohost-api": "YunoHostウェブインターフェイスとシステム間の連携を管理します",
"service_description_yunohost-firewall": "サービスへの接続ポートの開閉を管理", "service_description_yunohost-firewall": "サービスへの接続ポートの開閉を管理",
"service_description_yunomdns": "ローカルネットワークで「yunohost.local」を使用してサーバーに到達できます", "service_description_yunomdns": "ローカルネットワークで'yunohost.local'を使用してサーバーに到達できます",
"service_disable_failed": "起動時にサービス '{service}' を開始できませんでした。\n\n最近のサービスログ:{logs}", "service_disable_failed": "起動時にサービス '{service}' を開始できませんでした。\n\n最近のサービスログ:{logs}",
"service_disabled": "システムの起動時にサービス '{service}' は開始されなくなります。", "service_disabled": "システムの起動時にサービス '{service}' は自動開始されなくなります。",
"service_reload_failed": "サービス '{service}' をリロードできませんでした\n\n最近のサービスログ:{logs}", "service_reload_failed": "サービス '{service}' をリロードできませんでした\n\n最近のサービスログ:{logs}",
"service_reload_or_restart_failed": "サービス '{service}' をリロードまたは再起動できませんでした\n\n最近のサービスログ:{logs}", "service_reload_or_restart_failed": "サービス '{service}' をリロードまたは再起動できませんでした\n\n最近のサービスログ:{logs}",
"service_reloaded_or_restarted": "サービス '{service}' が再読み込みまたは再起動されました", "service_reloaded_or_restarted": "サービス '{service}' が再読み込みまたは再起動されました",
@ -730,12 +730,12 @@
"service_stopped": "サービス '{service}' が停止しました", "service_stopped": "サービス '{service}' が停止しました",
"service_unknown": "不明なサービス '{service}'", "service_unknown": "不明なサービス '{service}'",
"system_username_exists": "ユーザー名はシステムユーザーのリストにすでに存在します", "system_username_exists": "ユーザー名はシステムユーザーのリストにすでに存在します",
"this_action_broke_dpkg": "このアクションはdpkg / APT(システムパッケージマネージャ)を壊しました...SSH経由で接続し、「sudo apt install --fix-broken」および/または「sudo dpkg --configure -a」を実行することで、この問題を解決できます。", "this_action_broke_dpkg": "このアクションはdpkg / APT(システムパッケージマネージャ)を壊しました... SSH経由で接続し、sudo apt install --fix-broken および/または sudo dpkg --configure -a を実行することで、この問題を解決できるかもしれません。",
"tools_upgrade": "システムパッケージのアップグレード", "tools_upgrade": "システムパッケージのアップグレード",
"tools_upgrade_failed": "パッケージをアップグレードできませんでした: {packages_list}", "tools_upgrade_failed": "パッケージをアップグレードできませんでした: {packages_list}",
"unbackup_app": "{app}は保存されません", "unbackup_app": "{app}は保存されません",
"unexpected_error": "予期しない問題が発生しました:{error}", "unexpected_error": "予期しない問題が発生しました: {error}",
"unknown_main_domain_path": "'{app}' の不明なドメインまたはパス。アクセス許可の URL を指定できるようにするには、ドメインとパスを指定する必要があります。", "unknown_main_domain_path": "'{app}' のドメインまたはパスが不明です。アクセス許可の URL を指定できるようにするには、ドメインとパスを指定する必要があります。",
"unrestore_app": "{app}は復元されません", "unrestore_app": "{app}は復元されません",
"updating_apt_cache": "システムパッケージの利用可能なアップグレードを取得しています...", "updating_apt_cache": "システムパッケージの利用可能なアップグレードを取得しています...",
"upgrade_complete": "アップグレート完了", "upgrade_complete": "アップグレート完了",
@ -765,6 +765,6 @@
"yunohost_configured": "YunoHost が構成されました", "yunohost_configured": "YunoHost が構成されました",
"yunohost_installing": "YunoHostをインストールしています...", "yunohost_installing": "YunoHostをインストールしています...",
"yunohost_not_installed": "YunoHostが正しくインストールされていません。yunohost tools postinstall を実行してください", "yunohost_not_installed": "YunoHostが正しくインストールされていません。yunohost tools postinstall を実行してください",
"yunohost_postinstall_end_tip": "インストール後処理が完了しました!セットアップを完了するには、次の点を考慮してください。\n - ウェブ管理画面の「診断」セクション(またはコマンドラインでyunohost diagnosis run)を通じて潜在的な問題を診断します。\n - 管理ドキュメントの「セットアップの最終処理」と「YunoHostを知る」の部分を読む: https://yunohost.org/admindoc。", "yunohost_postinstall_end_tip": "インストール後処理が完了しました!セットアップを完了するには、次の点を考慮してください。\n - ウェブ管理画面の'診断'セクション(またはコマンドラインでyunohost diagnosis run)を通じて潜在的な問題を診断します。\n - 管理ドキュメントの'セットアップの最終処理'と'YunoHostを知る'の部分を読む: https://yunohost.org/admindoc。",
"additional_urls_already_removed": "アクセス許可 {permission} に対する追加URLで {url} は既に削除されています" "additional_urls_already_removed": "アクセス許可 {permission} に対する追加URLで {url} は既に削除されています"
} }

View file

@ -515,10 +515,16 @@ domain:
help: Domain name to add help: Domain name to add
extra: extra:
pattern: *pattern_domain pattern: *pattern_domain
-d: --ignore-dyndns:
full: --dyndns help: If adding a DynDNS domain, only add the domain, without subscribing to the DynDNS service
help: Subscribe to the DynDNS service
action: store_true action: store_true
--dyndns-recovery-password:
metavar: PASSWORD
nargs: "?"
const: 0
help: If adding a DynDNS domain, subscribe to the DynDNS service with a password, used to later delete the domain
extra:
pattern: *pattern_password
### domain_remove() ### domain_remove()
remove: remove:
@ -537,6 +543,16 @@ domain:
full: --force full: --force
help: Do not ask confirmation to remove apps help: Do not ask confirmation to remove apps
action: store_true action: store_true
--ignore-dyndns:
help: If removing a DynDNS domain, only remove the domain, without unsubscribing from the DynDNS service
action: store_true
--dyndns-recovery-password:
metavar: PASSWORD
nargs: "?"
const: 0
help: If removing a DynDNS domain, unsubscribe from the DynDNS service with a password
extra:
pattern: *pattern_password
### domain_dns_conf() ### domain_dns_conf()
@ -623,6 +639,7 @@ domain:
path: path:
help: The path to check (e.g. /coffee) help: The path to check (e.g. /coffee)
### domain_action_run() ### domain_action_run()
action-run: action-run:
hide_in_help: True hide_in_help: True
@ -638,11 +655,61 @@ domain:
help: Serialized arguments for action (i.e. "foo=bar&lorem=ipsum") help: Serialized arguments for action (i.e. "foo=bar&lorem=ipsum")
subcategories: subcategories:
dyndns:
subcategory_help: Subscribe and Update DynDNS Hosts
actions:
### domain_dyndns_subscribe()
subscribe:
action_help: Subscribe to a DynDNS service
arguments:
domain:
help: Domain to subscribe to the DynDNS service
extra:
pattern: *pattern_domain
-p:
full: --recovery-password
nargs: "?"
const: 0
help: Password used to later recover the domain if needed
extra:
pattern: *pattern_password
### domain_dyndns_unsubscribe()
unsubscribe:
action_help: Unsubscribe from a DynDNS service
arguments:
domain:
help: Domain to unsubscribe from the DynDNS service
extra:
pattern: *pattern_domain
required: True
-p:
full: --recovery-password
nargs: "?"
const: 0
help: Recovery password used to delete the domain
extra:
pattern: *pattern_password
### domain_dyndns_set_recovery_password()
set-recovery-password:
action_help: Set recovery password
arguments:
domain:
help: Domain to set recovery password for
extra:
pattern: *pattern_domain
required: True
-p:
full: --recovery-password
help: The new recovery password
extra:
password: ask_dyndns_recovery_password
pattern: *pattern_password
config: config:
subcategory_help: Domain settings subcategory_help: Domain settings
actions: actions:
### domain_config_get() ### domain_config_get()
get: get:
action_help: Display a domain configuration action_help: Display a domain configuration
@ -1516,21 +1583,26 @@ firewall:
# DynDNS # # DynDNS #
############################# #############################
dyndns: dyndns:
category_help: Subscribe and Update DynDNS Hosts category_help: Subscribe and Update DynDNS Hosts ( deprecated, use 'yunohost domain dyndns' instead )
actions: actions:
### dyndns_subscribe() ### dyndns_subscribe()
subscribe: subscribe:
action_help: Subscribe to a DynDNS service action_help: Subscribe to a DynDNS service
deprecated: true
arguments: arguments:
-d: -d:
full: --domain full: --domain
help: Full domain to subscribe with help: Full domain to subscribe with ( deprecated, use 'yunohost domain dyndns subscribe' instead )
extra: extra:
pattern: *pattern_domain pattern: *pattern_domain
-k: -p:
full: --key full: --recovery-password
help: Public DNS key nargs: "?"
const: 0
help: Password used to later recover the domain if needed
extra:
pattern: *pattern_password
### dyndns_update() ### dyndns_update()
update: update:
@ -1619,8 +1691,15 @@ tools:
required: True required: True
comment: good_practices_about_admin_password comment: good_practices_about_admin_password
--ignore-dyndns: --ignore-dyndns:
help: Do not subscribe domain to a DynDNS service help: If adding a DynDNS domain, only add the domain, without subscribing to the DynDNS service
action: store_true action: store_true
--dyndns-recovery-password:
metavar: PASSWORD
nargs: "?"
const: 0
help: If adding a DynDNS domain, subscribe to the DynDNS service with a password, used to later recover the domain if needed
extra:
pattern: *pattern_password
--force-diskspace: --force-diskspace:
help: Use this if you really want to install YunoHost on a setup with less than 10 GB on the root filesystem help: Use this if you really want to install YunoHost on a setup with less than 10 GB on the root filesystem
action: store_true action: store_true

View file

@ -19,8 +19,6 @@
import glob import glob
import os import os
import toml
import json
import shutil import shutil
import yaml import yaml
import time import time
@ -28,7 +26,6 @@ import re
import subprocess import subprocess
import tempfile import tempfile
import copy import copy
from collections import OrderedDict
from typing import List, Tuple, Dict, Any, Iterator, Optional from typing import List, Tuple, Dict, Any, Iterator, Optional
from packaging import version from packaging import version
@ -1099,7 +1096,7 @@ def app_install(
raw_questions = manifest["install"] raw_questions = manifest["install"]
questions = ask_questions_and_parse_answers(raw_questions, prefilled_answers=args) questions = ask_questions_and_parse_answers(raw_questions, prefilled_answers=args)
args = { args = {
question.name: question.value question.id: question.value
for question in questions for question in questions
if question.value is not None if question.value is not None
} }
@ -1147,7 +1144,7 @@ def app_install(
if question.type == "password": if question.type == "password":
continue continue
app_settings[question.name] = question.value app_settings[question.id] = question.value
_set_app_settings(app_instance_name, app_settings) _set_app_settings(app_instance_name, app_settings)
@ -1202,17 +1199,17 @@ def app_install(
# Reinject user-provider passwords which are not in the app settings # Reinject user-provider passwords which are not in the app settings
# (cf a few line before) # (cf a few line before)
if question.type == "password": if question.type == "password":
env_dict[question.name] = question.value env_dict[question.id] = question.value
# We want to hav the env_dict in the log ... but not password values # We want to hav the env_dict in the log ... but not password values
env_dict_for_logging = env_dict.copy() env_dict_for_logging = env_dict.copy()
for question in questions: for question in questions:
# Or should it be more generally question.redact ? # Or should it be more generally question.redact ?
if question.type == "password": if question.type == "password":
if f"YNH_APP_ARG_{question.name.upper()}" in env_dict_for_logging: if f"YNH_APP_ARG_{question.id.upper()}" in env_dict_for_logging:
del env_dict_for_logging[f"YNH_APP_ARG_{question.name.upper()}"] del env_dict_for_logging[f"YNH_APP_ARG_{question.id.upper()}"]
if question.name in env_dict_for_logging: if question.id in env_dict_for_logging:
del env_dict_for_logging[question.name] del env_dict_for_logging[question.id]
operation_logger.extra.update({"env": env_dict_for_logging}) operation_logger.extra.update({"env": env_dict_for_logging})
@ -1636,6 +1633,9 @@ def app_setting(app, key, value=None, delete=False):
if delete: if delete:
if key in app_settings: if key in app_settings:
del app_settings[key] del app_settings[key]
else:
# Don't call _set_app_settings to avoid unecessary writes...
return
# SET # SET
else: else:
@ -1961,31 +1961,6 @@ ynh_app_config_run $1
return values return values
def _get_app_actions(app_id):
"Get app config panel stored in json or in toml"
actions_toml_path = os.path.join(APPS_SETTING_PATH, app_id, "actions.toml")
actions_json_path = os.path.join(APPS_SETTING_PATH, app_id, "actions.json")
if os.path.exists(actions_toml_path):
toml_actions = toml.load(open(actions_toml_path, "r"), _dict=OrderedDict)
# transform toml format into json format
actions = []
for key, value in toml_actions.items():
action = dict(**value)
action["id"] = key
action["arguments"] = value.get("arguments", {})
actions.append(action)
return actions
elif os.path.exists(actions_json_path):
return json.load(open(actions_json_path))
return None
def _get_app_settings(app): def _get_app_settings(app):
""" """
Get settings of an installed app Get settings of an installed app
@ -2373,18 +2348,16 @@ def _set_default_ask_questions(questions, script_name="install"):
), # i18n: app_manifest_install_ask_init_admin_permission ), # i18n: app_manifest_install_ask_init_admin_permission
] ]
for question_name, question in questions.items(): for question_id, question in questions.items():
question["name"] = question_name question["id"] = question_id
# If this question corresponds to a question with default ask message... # If this question corresponds to a question with default ask message...
if any( if any(
(question.get("type"), question["name"]) == question_with_default (question.get("type"), question["id"]) == question_with_default
for question_with_default in questions_with_default for question_with_default in questions_with_default
): ):
# The key is for example "app_manifest_install_ask_domain" # The key is for example "app_manifest_install_ask_domain"
question["ask"] = m18n.n( question["ask"] = m18n.n(f"app_manifest_{script_name}_ask_{question['id']}")
f"app_manifest_{script_name}_ask_{question['name']}"
)
# Also it in fact doesn't make sense for any of those questions to have an example value nor a default value... # Also it in fact doesn't make sense for any of those questions to have an example value nor a default value...
if question.get("type") in ["domain", "user", "password"]: if question.get("type") in ["domain", "user", "password"]:
@ -3231,3 +3204,47 @@ def _ask_confirmation(
if not answer: if not answer:
raise YunohostError("aborting") raise YunohostError("aborting")
def regen_mail_app_user_config_for_dovecot_and_postfix(only=None):
dovecot = True if only in [None, "dovecot"] else False
postfix = True if only in [None, "postfix"] else False
from yunohost.user import _hash_user_password
postfix_map = []
dovecot_passwd = []
for app in _installed_apps():
settings = _get_app_settings(app)
if "domain" not in settings or "mail_pwd" not in settings:
continue
if dovecot:
hashed_password = _hash_user_password(settings["mail_pwd"])
dovecot_passwd.append(
f"{app}:{hashed_password}::::::allow_nets=127.0.0.1/24"
)
if postfix:
mail_user = settings.get("mail_user", app)
mail_domain = settings.get("mail_domain", settings["domain"])
postfix_map.append(f"{mail_user}@{mail_domain} {app}")
if dovecot:
app_senders_passwd = "/etc/dovecot/app-senders-passwd"
content = "# This file is regenerated automatically.\n# Please DO NOT edit manually ... changes will be overwritten!"
content += "\n" + "\n".join(dovecot_passwd)
write_to_file(app_senders_passwd, content)
chmod(app_senders_passwd, 0o440)
chown(app_senders_passwd, "root", "dovecot")
if postfix:
app_senders_map = "/etc/postfix/app_senders_login_maps"
content = "# This file is regenerated automatically.\n# Please DO NOT edit manually ... changes will be overwritten!"
content += "\n" + "\n".join(postfix_map)
write_to_file(app_senders_map, content)
chmod(app_senders_map, 0o440)
chown(app_senders_map, "postfix", "root")
os.system(f"postmap {app_senders_map} 2>/dev/null")
chmod(app_senders_map + ".db", 0o640)
chown(app_senders_map + ".db", "postfix", "root")

View file

@ -640,18 +640,29 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
# FIXME: in the future, properly unify this with yunohost dyndns update # FIXME: in the future, properly unify this with yunohost dyndns update
if registrar == "yunohost": if registrar == "yunohost":
logger.info(m18n.n("domain_dns_registrar_yunohost")) from yunohost.dyndns import dyndns_update
dyndns_update(domain=domain, force=force)
return {} return {}
if registrar == "parent_domain": if registrar == "parent_domain":
parent_domain = _get_parent_domain_of(domain, topest=True) parent_domain = _get_parent_domain_of(domain, topest=True)
registar, registrar_credentials = _get_registar_settings(parent_domain) registrar, registrar_credentials = _get_registar_settings(parent_domain)
if any(registrar_credentials.values()): if any(registrar_credentials.values()):
raise YunohostValidationError( raise YunohostValidationError(
"domain_dns_push_managed_in_parent_domain", "domain_dns_push_managed_in_parent_domain",
domain=domain, domain=domain,
parent_domain=parent_domain, parent_domain=parent_domain,
) )
else:
new_parent_domain = ".".join(parent_domain.split(".")[-3:])
registrar, registrar_credentials = _get_registar_settings(new_parent_domain)
if registrar == "yunohost":
raise YunohostValidationError(
"domain_dns_push_managed_in_parent_domain",
domain=domain,
parent_domain=new_parent_domain,
)
else: else:
raise YunohostValidationError( raise YunohostValidationError(
"domain_registrar_is_not_configured", domain=parent_domain "domain_registrar_is_not_configured", domain=parent_domain

View file

@ -36,6 +36,7 @@ from yunohost.regenconf import regen_conf, _force_clear_hashes, _process_regen_c
from yunohost.utils.configpanel import ConfigPanel from yunohost.utils.configpanel import ConfigPanel
from yunohost.utils.form import BaseOption from yunohost.utils.form import BaseOption
from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.utils.error import YunohostError, YunohostValidationError
from yunohost.utils.dns import is_yunohost_dyndns_domain
from yunohost.log import is_unit_operation from yunohost.log import is_unit_operation
logger = getActionLogger("yunohost.domain") logger = getActionLogger("yunohost.domain")
@ -230,21 +231,28 @@ def _get_parent_domain_of(domain, return_self=False, topest=False):
return domain if return_self else None return domain if return_self else None
@is_unit_operation() @is_unit_operation(exclude=["dyndns_recovery_password"])
def domain_add(operation_logger, domain, dyndns=False): def domain_add(
operation_logger, domain, dyndns_recovery_password=None, ignore_dyndns=False
):
""" """
Create a custom domain Create a custom domain
Keyword argument: Keyword argument:
domain -- Domain name to add domain -- Domain name to add
dyndns -- Subscribe to DynDNS dyndns -- Subscribe to DynDNS
dyndns_recovery_password -- Password used to later unsubscribe from DynDNS
ignore_dyndns -- If we want to just add the DynDNS domain to the list, without subscribing
""" """
from yunohost.hook import hook_callback from yunohost.hook import hook_callback
from yunohost.app import app_ssowatconf from yunohost.app import app_ssowatconf
from yunohost.utils.ldap import _get_ldap_interface from yunohost.utils.ldap import _get_ldap_interface
from yunohost.utils.password import assert_password_is_strong_enough
from yunohost.certificate import _certificate_install_selfsigned from yunohost.certificate import _certificate_install_selfsigned
if dyndns_recovery_password:
operation_logger.data_to_redact.append(dyndns_recovery_password)
if domain.startswith("xmpp-upload."): if domain.startswith("xmpp-upload."):
raise YunohostValidationError("domain_cannot_add_xmpp_upload") raise YunohostValidationError("domain_cannot_add_xmpp_upload")
@ -265,27 +273,27 @@ def domain_add(operation_logger, domain, dyndns=False):
# Non-latin characters (e.g. café.com => xn--caf-dma.com) # Non-latin characters (e.g. café.com => xn--caf-dma.com)
domain = domain.encode("idna").decode("utf-8") domain = domain.encode("idna").decode("utf-8")
# DynDNS domain # Detect if this is a DynDNS domain ( and not a subdomain of a DynDNS domain )
dyndns = (
not ignore_dyndns
and is_yunohost_dyndns_domain(domain)
and len(domain.split(".")) == 3
)
if dyndns: if dyndns:
from yunohost.utils.dns import is_yunohost_dyndns_domain from yunohost.dyndns import is_subscribing_allowed
from yunohost.dyndns import _guess_current_dyndns_domain
# Do not allow to subscribe to multiple dyndns domains... # Do not allow to subscribe to multiple dyndns domains...
if _guess_current_dyndns_domain() != (None, None): if not is_subscribing_allowed():
raise YunohostValidationError("domain_dyndns_already_subscribed") raise YunohostValidationError("domain_dyndns_already_subscribed")
if dyndns_recovery_password:
# Check that this domain can effectively be provided by assert_password_is_strong_enough("admin", dyndns_recovery_password)
# dyndns.yunohost.org. (i.e. is it a nohost.me / noho.st)
if not is_yunohost_dyndns_domain(domain):
raise YunohostValidationError("domain_dyndns_root_unknown")
operation_logger.start() operation_logger.start()
if dyndns: if dyndns:
from yunohost.dyndns import dyndns_subscribe domain_dyndns_subscribe(
domain=domain, recovery_password=dyndns_recovery_password
# Actually subscribe )
dyndns_subscribe(domain=domain)
_certificate_install_selfsigned([domain], True) _certificate_install_selfsigned([domain], True)
@ -334,8 +342,15 @@ def domain_add(operation_logger, domain, dyndns=False):
logger.success(m18n.n("domain_created")) logger.success(m18n.n("domain_created"))
@is_unit_operation() @is_unit_operation(exclude=["dyndns_recovery_password"])
def domain_remove(operation_logger, domain, remove_apps=False, force=False): def domain_remove(
operation_logger,
domain,
remove_apps=False,
force=False,
dyndns_recovery_password=None,
ignore_dyndns=False,
):
""" """
Delete domains Delete domains
@ -344,12 +359,16 @@ def domain_remove(operation_logger, domain, remove_apps=False, force=False):
remove_apps -- Remove applications installed on the domain remove_apps -- Remove applications installed on the domain
force -- Force the domain removal and don't not ask confirmation to force -- Force the domain removal and don't not ask confirmation to
remove apps if remove_apps is specified remove apps if remove_apps is specified
dyndns_recovery_password -- Recovery password used at the creation of the DynDNS domain
ignore_dyndns -- If we just remove the DynDNS domain, without unsubscribing
""" """
from yunohost.hook import hook_callback from yunohost.hook import hook_callback
from yunohost.app import app_ssowatconf, app_info, app_remove from yunohost.app import app_ssowatconf, app_info, app_remove
from yunohost.utils.ldap import _get_ldap_interface from yunohost.utils.ldap import _get_ldap_interface
if dyndns_recovery_password:
operation_logger.data_to_redact.append(dyndns_recovery_password)
# the 'force' here is related to the exception happening in domain_add ... # the 'force' here is related to the exception happening in domain_add ...
# we don't want to check the domain exists because the ldap add may have # we don't want to check the domain exists because the ldap add may have
# failed # failed
@ -410,6 +429,13 @@ def domain_remove(operation_logger, domain, remove_apps=False, force=False):
apps="\n".join([x[1] for x in apps_on_that_domain]), apps="\n".join([x[1] for x in apps_on_that_domain]),
) )
# Detect if this is a DynDNS domain ( and not a subdomain of a DynDNS domain )
dyndns = (
not ignore_dyndns
and is_yunohost_dyndns_domain(domain)
and len(domain.split(".")) == 3
)
operation_logger.start() operation_logger.start()
ldap = _get_ldap_interface() ldap = _get_ldap_interface()
@ -456,9 +482,61 @@ def domain_remove(operation_logger, domain, remove_apps=False, force=False):
hook_callback("post_domain_remove", args=[domain]) hook_callback("post_domain_remove", args=[domain])
# If a password is provided, delete the DynDNS record
if dyndns:
# Actually unsubscribe
domain_dyndns_unsubscribe(
domain=domain, recovery_password=dyndns_recovery_password
)
logger.success(m18n.n("domain_deleted")) logger.success(m18n.n("domain_deleted"))
def domain_dyndns_subscribe(*args, **kwargs):
"""
Subscribe to a DynDNS domain
"""
from yunohost.dyndns import dyndns_subscribe
dyndns_subscribe(*args, **kwargs)
def domain_dyndns_unsubscribe(*args, **kwargs):
"""
Unsubscribe from a DynDNS domain
"""
from yunohost.dyndns import dyndns_unsubscribe
dyndns_unsubscribe(*args, **kwargs)
def domain_dyndns_list():
"""
Returns all currently subscribed DynDNS domains
"""
from yunohost.dyndns import dyndns_list
return dyndns_list()
def domain_dyndns_update(*args, **kwargs):
"""
Update a DynDNS domain
"""
from yunohost.dyndns import dyndns_update
dyndns_update(*args, **kwargs)
def domain_dyndns_set_recovery_password(*args, **kwargs):
"""
Set a recovery password for an already registered dyndns domain
"""
from yunohost.dyndns import dyndns_set_recovery_password
dyndns_set_recovery_password(*args, **kwargs)
@is_unit_operation() @is_unit_operation()
def domain_main_domain(operation_logger, new_main_domain=None): def domain_main_domain(operation_logger, new_main_domain=None):
""" """

View file

@ -17,13 +17,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import os import os
import re
import json import json
import glob import glob
import base64 import base64
import subprocess import subprocess
import hashlib
from moulinette import m18n from moulinette import Moulinette, m18n
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
from moulinette.utils.log import getActionLogger from moulinette.utils.log import getActionLogger
from moulinette.utils.filesystem import write_to_file, rm, chown, chmod from moulinette.utils.filesystem import write_to_file, rm, chown, chmod
@ -40,6 +40,17 @@ logger = getActionLogger("yunohost.dyndns")
DYNDNS_PROVIDER = "dyndns.yunohost.org" DYNDNS_PROVIDER = "dyndns.yunohost.org"
DYNDNS_DNS_AUTH = ["ns0.yunohost.org", "ns1.yunohost.org"] DYNDNS_DNS_AUTH = ["ns0.yunohost.org", "ns1.yunohost.org"]
MAX_DYNDNS_DOMAINS = 1
def is_subscribing_allowed():
"""
Check if the limit of subscribed DynDNS domains has been reached
Returns:
True if the limit is not reached, False otherwise
"""
return len(dyndns_list()["domains"]) < MAX_DYNDNS_DOMAINS
def _dyndns_available(domain): def _dyndns_available(domain):
@ -67,23 +78,16 @@ def _dyndns_available(domain):
return r == f"Domain {domain} is available" return r == f"Domain {domain} is available"
@is_unit_operation() @is_unit_operation(exclude=["recovery_password"])
def dyndns_subscribe(operation_logger, domain=None, key=None): def dyndns_subscribe(operation_logger, domain=None, recovery_password=None):
""" """
Subscribe to a DynDNS service Subscribe to a DynDNS service
Keyword argument: Keyword argument:
domain -- Full domain to subscribe with domain -- Full domain to subscribe with
key -- Public DNS key recovery_password -- Password that will be used to delete the domain
""" """
if _guess_current_dyndns_domain() != (None, None):
raise YunohostValidationError("domain_dyndns_already_subscribed")
if domain is None:
domain = _get_maindomain()
operation_logger.related_to.append(("domain", domain))
# Verify if domain is provided by subscribe_host # Verify if domain is provided by subscribe_host
if not is_yunohost_dyndns_domain(domain): if not is_yunohost_dyndns_domain(domain):
raise YunohostValidationError( raise YunohostValidationError(
@ -94,19 +98,39 @@ def dyndns_subscribe(operation_logger, domain=None, key=None):
if not _dyndns_available(domain): if not _dyndns_available(domain):
raise YunohostValidationError("dyndns_unavailable", domain=domain) raise YunohostValidationError("dyndns_unavailable", domain=domain)
# Check adding another dyndns domain is still allowed
if not is_subscribing_allowed():
raise YunohostValidationError("domain_dyndns_already_subscribed")
# Prompt for a password if running in CLI and no password provided
if not recovery_password and Moulinette.interface.type == "cli":
logger.warning(m18n.n("ask_dyndns_recovery_password_explain"))
recovery_password = Moulinette.prompt(
m18n.n("ask_dyndns_recovery_password"), is_password=True, confirm=True
)
if not recovery_password:
logger.warning(m18n.n("dyndns_no_recovery_password"))
if recovery_password:
from yunohost.utils.password import assert_password_is_strong_enough
assert_password_is_strong_enough("admin", recovery_password)
operation_logger.data_to_redact.append(recovery_password)
if domain is None:
domain = _get_maindomain()
operation_logger.related_to.append(("domain", domain))
operation_logger.start() operation_logger.start()
# '165' is the convention identifier for hmac-sha512 algorithm # '165' is the convention identifier for hmac-sha512 algorithm
# '1234' is idk? doesnt matter, but the old format contained a number here... # '1234' is idk? doesnt matter, but the old format contained a number here...
key_file = f"/etc/yunohost/dyndns/K{domain}.+165+1234.key" key_file = f"/etc/yunohost/dyndns/K{domain}.+165+1234.key"
if key is None:
if len(glob.glob("/etc/yunohost/dyndns/*.key")) == 0:
if not os.path.exists("/etc/yunohost/dyndns"): if not os.path.exists("/etc/yunohost/dyndns"):
os.makedirs("/etc/yunohost/dyndns") os.makedirs("/etc/yunohost/dyndns")
logger.debug(m18n.n("dyndns_key_generating"))
# Here, we emulate the behavior of the old 'dnssec-keygen' utility # Here, we emulate the behavior of the old 'dnssec-keygen' utility
# which since bullseye was replaced by ddns-keygen which is now # which since bullseye was replaced by ddns-keygen which is now
# in the bind9 package ... but installing bind9 will conflict with dnsmasq # in the bind9 package ... but installing bind9 will conflict with dnsmasq
@ -131,21 +155,26 @@ def dyndns_subscribe(operation_logger, domain=None, key=None):
try: try:
# Yeah the secret is already a base64-encoded but we double-bas64-encode it, whatever... # Yeah the secret is already a base64-encoded but we double-bas64-encode it, whatever...
b64encoded_key = base64.b64encode(secret.encode()).decode() b64encoded_key = base64.b64encode(secret.encode()).decode()
data = {"subdomain": domain}
if recovery_password:
data["recovery_password"] = hashlib.sha256(
(domain + ":" + recovery_password.strip()).encode("utf-8")
).hexdigest()
r = requests.post( r = requests.post(
f"https://{DYNDNS_PROVIDER}/key/{b64encoded_key}?key_algo=hmac-sha512", f"https://{DYNDNS_PROVIDER}/key/{b64encoded_key}?key_algo=hmac-sha512",
data={"subdomain": domain}, data=data,
timeout=30, timeout=30,
) )
except Exception as e: except Exception as e:
rm(key_file, force=True) rm(key_file, force=True)
raise YunohostError("dyndns_registration_failed", error=str(e)) raise YunohostError("dyndns_subscribe_failed", error=str(e))
if r.status_code != 201: if r.status_code != 201:
rm(key_file, force=True) rm(key_file, force=True)
try: try:
error = json.loads(r.text)["error"] error = json.loads(r.text)["error"]
except Exception: except Exception:
error = f'Server error, code: {r.status_code}. (Message: "{r.text}")' error = f'Server error, code: {r.status_code}. (Message: "{r.text}")'
raise YunohostError("dyndns_registration_failed", error=error) raise YunohostError("dyndns_subscribe_failed", error=error)
# Yunohost regen conf will add the dyndns cron job if a key exists # Yunohost regen conf will add the dyndns cron job if a key exists
# in /etc/yunohost/dyndns # in /etc/yunohost/dyndns
@ -160,7 +189,143 @@ def dyndns_subscribe(operation_logger, domain=None, key=None):
subprocess.check_call(["bash", "-c", cmd.format(t="2 min")]) subprocess.check_call(["bash", "-c", cmd.format(t="2 min")])
subprocess.check_call(["bash", "-c", cmd.format(t="4 min")]) subprocess.check_call(["bash", "-c", cmd.format(t="4 min")])
logger.success(m18n.n("dyndns_registered")) logger.success(m18n.n("dyndns_subscribed"))
@is_unit_operation(exclude=["recovery_password"])
def dyndns_unsubscribe(operation_logger, domain, recovery_password=None):
"""
Unsubscribe from a DynDNS service
Keyword argument:
domain -- Full domain to unsubscribe with
recovery_password -- Password that is used to delete the domain ( defined when subscribing )
"""
import requests # lazy loading this module for performance reasons
# Unsubscribe the domain using the key if available
keys = glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*.key")
if keys:
key = keys[0]
with open(key) as f:
key = f.readline().strip().split(" ", 6)[-1]
base64key = base64.b64encode(key.encode()).decode()
credential = {"key": base64key}
# Otherwise, ask for the recovery password
else:
if Moulinette.interface.type == "cli" and not recovery_password:
logger.warning(
m18n.n("ask_dyndns_recovery_password_explain_during_unsubscribe")
)
recovery_password = Moulinette.prompt(
m18n.n("ask_dyndns_recovery_password"), is_password=True
)
if not recovery_password:
logger.error(
f"Cannot unsubscribe the domain {domain}: no credential provided"
)
return
secret = str(domain) + ":" + str(recovery_password).strip()
credential = {
"recovery_password": hashlib.sha256(secret.encode("utf-8")).hexdigest()
}
operation_logger.start()
# Send delete request
try:
r = requests.delete(
f"https://{DYNDNS_PROVIDER}/domains/{domain}",
data=credential,
timeout=30,
)
except Exception as e:
raise YunohostError("dyndns_unsubscribe_failed", error=str(e))
if r.status_code == 200: # Deletion was successful
for key_file in glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*.key"):
rm(key_file, force=True)
# Yunohost regen conf will add the dyndns cron job if a key exists
# in /etc/yunohost/dyndns
regen_conf(["yunohost"])
elif r.status_code == 403:
raise YunohostError("dyndns_unsubscribe_denied")
elif r.status_code == 409:
raise YunohostError("dyndns_unsubscribe_already_unsubscribed")
else:
raise YunohostError(
"dyndns_unsubscribe_failed",
error=f"The server returned code {r.status_code}",
)
logger.success(m18n.n("dyndns_unsubscribed"))
def dyndns_set_recovery_password(domain, recovery_password):
keys = glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*.key")
if not keys:
raise YunohostValidationError("dyndns_key_not_found")
from yunohost.utils.password import assert_password_is_strong_enough
assert_password_is_strong_enough("admin", recovery_password)
secret = str(domain) + ":" + str(recovery_password).strip()
key = keys[0]
with open(key) as f:
key = f.readline().strip().split(" ", 6)[-1]
base64key = base64.b64encode(key.encode()).decode()
import requests # lazy loading this module for performance reasons
# Send delete request
try:
r = requests.put(
f"https://{DYNDNS_PROVIDER}/domains/{domain}/recovery_password",
data={
"key": base64key,
"recovery_password": hashlib.sha256(secret.encode("utf-8")).hexdigest(),
},
timeout=30,
)
except Exception as e:
raise YunohostError("dyndns_set_recovery_password_failed", error=str(e))
if r.status_code == 200:
logger.success(m18n.n("dyndns_set_recovery_password_success"))
elif r.status_code == 403:
raise YunohostError("dyndns_set_recovery_password_denied")
elif r.status_code == 404:
raise YunohostError("dyndns_set_recovery_password_unknown_domain")
elif r.status_code == 409:
raise YunohostError("dyndns_set_recovery_password_invalid_password")
else:
raise YunohostError(
"dyndns_set_recovery_password_failed",
error=f"The server returned code {r.status_code}",
)
def dyndns_list():
"""
Returns all currently subscribed DynDNS domains ( deduced from the key files )
"""
from yunohost.domain import domain_list
domains = domain_list(exclude_subdomains=True)["domains"]
dyndns_domains = [
d
for d in domains
if is_yunohost_dyndns_domain(d)
and glob.glob(f"/etc/yunohost/dyndns/K{d}.+*.key")
]
return {"domains": dyndns_domains}
@is_unit_operation() @is_unit_operation()
@ -183,16 +348,19 @@ def dyndns_update(
import dns.tsigkeyring import dns.tsigkeyring
import dns.update import dns.update
# If domain is not given, try to guess it from keys available... # If domain is not given, update all DynDNS domains
key = None
if domain is None: if domain is None:
(domain, key) = _guess_current_dyndns_domain() dyndns_domains = dyndns_list()["domains"]
if domain is None: if not dyndns_domains:
raise YunohostValidationError("dyndns_no_domain_registered") raise YunohostValidationError("dyndns_no_domain_registered")
for domain in dyndns_domains:
dyndns_update(domain, force=force, dry_run=dry_run)
return
# If key is not given, pick the first file we find with the domain given # If key is not given, pick the first file we find with the domain given
elif key is None:
keys = glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*.key") keys = glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*.key")
if not keys: if not keys:
@ -330,34 +498,3 @@ def dyndns_update(
print( print(
"Warning: dry run, this is only the generated config, it won't be applied" "Warning: dry run, this is only the generated config, it won't be applied"
) )
def _guess_current_dyndns_domain():
"""
This function tries to guess which domain should be updated by
"dyndns_update()" because there's not proper management of the current
dyndns domain :/ (and at the moment the code doesn't support having several
dyndns domain, which is sort of a feature so that people don't abuse the
dynette...)
"""
DYNDNS_KEY_REGEX = re.compile(r".*/K(?P<domain>[^\s\+]+)\.\+165.+\.key$")
# Retrieve the first registered domain
paths = list(glob.iglob("/etc/yunohost/dyndns/K*.key"))
for path in paths:
match = DYNDNS_KEY_REGEX.match(path)
if not match:
continue
_domain = match.group("domain")
# Verify if domain is registered (i.e., if it's available, skip
# current domain beause that's not the one we want to update..)
# If there's only 1 such key found, then avoid doing the request
# for nothing (that's very probably the one we want to find ...)
if len(paths) > 1 and _dyndns_available(_domain):
continue
else:
return (_domain, path)
return (None, None)

View file

@ -1,5 +1,7 @@
import pytest import pytest
import os import os
import time
import random
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
@ -16,6 +18,12 @@ from yunohost.domain import (
) )
TEST_DOMAINS = ["example.tld", "sub.example.tld", "other-example.com"] TEST_DOMAINS = ["example.tld", "sub.example.tld", "other-example.com"]
TEST_DYNDNS_DOMAIN = (
"ci-test-"
+ "".join(chr(random.randint(ord("a"), ord("z"))) for x in range(12))
+ random.choice([".noho.st", ".ynh.fr", ".nohost.me"])
)
TEST_DYNDNS_PASSWORD = "astrongandcomplicatedpassphrasethatisverysecure"
def setup_function(function): def setup_function(function):
@ -34,7 +42,9 @@ def setup_function(function):
# Clear other domains # Clear other domains
for domain in domains: for domain in domains:
if domain not in TEST_DOMAINS or domain == TEST_DOMAINS[2]: if (
domain not in TEST_DOMAINS or domain == TEST_DOMAINS[2]
) and domain != TEST_DYNDNS_DOMAIN:
# Clean domains not used for testing # Clean domains not used for testing
domain_remove(domain) domain_remove(domain)
elif domain in TEST_DOMAINS: elif domain in TEST_DOMAINS:
@ -65,6 +75,13 @@ def test_domain_add():
assert TEST_DOMAINS[2] in domain_list()["domains"] assert TEST_DOMAINS[2] in domain_list()["domains"]
def test_domain_add_subscribe():
time.sleep(35) # Dynette blocks requests that happen too frequently
assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"]
domain_add(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD)
assert TEST_DYNDNS_DOMAIN in domain_list()["domains"]
def test_domain_add_existing_domain(): def test_domain_add_existing_domain():
with pytest.raises(MoulinetteError): with pytest.raises(MoulinetteError):
assert TEST_DOMAINS[1] in domain_list()["domains"] assert TEST_DOMAINS[1] in domain_list()["domains"]
@ -77,6 +94,13 @@ def test_domain_remove():
assert TEST_DOMAINS[1] not in domain_list()["domains"] assert TEST_DOMAINS[1] not in domain_list()["domains"]
def test_domain_remove_unsubscribe():
time.sleep(35) # Dynette blocks requests that happen too frequently
assert TEST_DYNDNS_DOMAIN in domain_list()["domains"]
domain_remove(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD)
assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"]
def test_main_domain(): def test_main_domain():
current_main_domain = _get_maindomain() current_main_domain = _get_maindomain()
assert domain_main_domain()["current_main_domain"] == current_main_domain assert domain_main_domain()["current_main_domain"] == current_main_domain

View file

@ -17,7 +17,9 @@ from yunohost import app, domain, user
from yunohost.utils.form import ( from yunohost.utils.form import (
OPTIONS, OPTIONS,
ask_questions_and_parse_answers, ask_questions_and_parse_answers,
DisplayTextOption, BaseChoicesOption,
BaseInputOption,
BaseReadonlyOption,
PasswordOption, PasswordOption,
DomainOption, DomainOption,
WebPathOption, WebPathOption,
@ -31,7 +33,7 @@ from yunohost.utils.error import YunohostError, YunohostValidationError
""" """
Argument default format: Argument default format:
{ {
"the_name": { "the_id": {
"type": "one_of_the_available_type", // "sting" is not specified "type": "one_of_the_available_type", // "sting" is not specified
"ask": { "ask": {
"en": "the question in english", "en": "the question in english",
@ -48,7 +50,7 @@ Argument default format:
} }
User answers: User answers:
{"the_name": "value", ...} {"the_id": "value", ...}
""" """
@ -377,8 +379,7 @@ def _fill_or_prompt_one_option(raw_option, intake):
answers = {id_: intake} if intake is not None else {} answers = {id_: intake} if intake is not None else {}
option = ask_questions_and_parse_answers(options, answers)[0] option = ask_questions_and_parse_answers(options, answers)[0]
return (option, option.value if isinstance(option, BaseInputOption) else None)
return (option, option.value)
def _test_value_is_expected_output(value, expected_output): def _test_value_is_expected_output(value, expected_output):
@ -438,14 +439,14 @@ class BaseTest:
id_ = raw_option["id"] id_ = raw_option["id"]
option, value = _fill_or_prompt_one_option(raw_option, None) option, value = _fill_or_prompt_one_option(raw_option, None)
is_special_readonly_option = isinstance(option, DisplayTextOption) is_special_readonly_option = isinstance(option, BaseReadonlyOption)
assert isinstance(option, OPTIONS[raw_option["type"]]) assert isinstance(option, OPTIONS[raw_option["type"]])
assert option.type == raw_option["type"] assert option.type == raw_option["type"]
assert option.name == id_ assert option.id == id_
assert option.ask == {"en": id_} assert option.ask == {"en": id_}
assert option.readonly is (True if is_special_readonly_option else False) assert option.readonly is (True if is_special_readonly_option else False)
assert option.visible is None assert option.visible is True
# assert option.bind is None # assert option.bind is None
if is_special_readonly_option: if is_special_readonly_option:
@ -489,13 +490,11 @@ class BaseTest:
option, value = _fill_or_prompt_one_option(raw_option, None) option, value = _fill_or_prompt_one_option(raw_option, None)
expected_message = option.ask["en"] expected_message = option.ask["en"]
choices = []
if option.choices: if isinstance(option, BaseChoicesOption):
choices = ( choices = option.choices
option.choices if choices:
if isinstance(option.choices, list)
else option.choices.keys()
)
expected_message += f" [{' | '.join(choices)}]" expected_message += f" [{' | '.join(choices)}]"
if option.type == "boolean": if option.type == "boolean":
expected_message += " [yes | no]" expected_message += " [yes | no]"
@ -506,7 +505,7 @@ class BaseTest:
confirm=False, # FIXME no confirm? confirm=False, # FIXME no confirm?
prefill=prefill, prefill=prefill,
is_multiline=option.type == "text", is_multiline=option.type == "text",
autocomplete=option.choices or [], autocomplete=choices,
help=option.help["en"], help=option.help["en"],
) )
@ -661,9 +660,7 @@ class TestString(BaseTest):
(" ##value \n \tvalue\n ", "##value \n \tvalue"), (" ##value \n \tvalue\n ", "##value \n \tvalue"),
], reason=r"should fail or without `\n`?"), ], reason=r"should fail or without `\n`?"),
# readonly # readonly
*xfail(scenarios=[ ("overwrite", "expected value", {"readonly": True, "current_value": "expected value"}),
("overwrite", "expected value", {"readonly": True, "default": "expected value"}),
], reason="Should not be overwritten"),
] ]
# fmt: on # fmt: on
@ -700,9 +697,7 @@ class TestText(BaseTest):
(r" ##value \n \tvalue\n ", r"##value \n \tvalue\n"), (r" ##value \n \tvalue\n ", r"##value \n \tvalue\n"),
], reason="Should not be stripped"), ], reason="Should not be stripped"),
# readonly # readonly
*xfail(scenarios=[ ("overwrite", "expected value", {"readonly": True, "current_value": "expected value"}),
("overwrite", "expected value", {"readonly": True, "default": "expected value"}),
], reason="Should not be overwritten"),
] ]
# fmt: on # fmt: on
@ -736,9 +731,7 @@ class TestPassword(BaseTest):
("secret", FAIL), ("secret", FAIL),
*[("supersecret" + char, FAIL) for char in PasswordOption.forbidden_chars], # FIXME maybe add ` \n` to the list? *[("supersecret" + char, FAIL) for char in PasswordOption.forbidden_chars], # FIXME maybe add ` \n` to the list?
# readonly # readonly
*xpass(scenarios=[ ("s3cr3t!!", YunohostError, {"readonly": True, "current_value": "isforbidden"}), # readonly is forbidden
("s3cr3t!!", "s3cr3t!!", {"readonly": True}),
], reason="Should fail since readonly is forbidden"),
] ]
# fmt: on # fmt: on
@ -779,9 +772,7 @@ class TestColor(BaseTest):
("yellow", "#ffff00"), ("yellow", "#ffff00"),
], reason="Should work with pydantic"), ], reason="Should work with pydantic"),
# readonly # readonly
*xfail(scenarios=[ ("#ffff00", "#fe100", {"readonly": True, "current_value": "#fe100"}),
("#ffff00", "#fe100", {"readonly": True, "default": "#fe100"}),
], reason="Should not be overwritten"),
] ]
# fmt: on # fmt: on
@ -823,9 +814,7 @@ class TestNumber(BaseTest):
(-10, -10, {"default": 10}), (-10, -10, {"default": 10}),
(-10, -10, {"default": 10, "optional": True}), (-10, -10, {"default": 10, "optional": True}),
# readonly # readonly
*xfail(scenarios=[ (1337, 10000, {"readonly": True, "current_value": 10000}),
(1337, 10000, {"readonly": True, "default": 10000}),
], reason="Should not be overwritten"),
] ]
# fmt: on # fmt: on
# FIXME should `step` be some kind of "multiple of"? # FIXME should `step` be some kind of "multiple of"?
@ -890,9 +879,7 @@ class TestBoolean(BaseTest):
"scenarios": all_fails("", "y", "n", error=AssertionError), "scenarios": all_fails("", "y", "n", error=AssertionError),
}, },
# readonly # readonly
*xfail(scenarios=[ (1, 0, {"readonly": True, "current_value": 0}),
(1, 0, {"readonly": True, "default": 0}),
], reason="Should not be overwritten"),
] ]
@ -930,9 +917,7 @@ class TestDate(BaseTest):
("12-01-10", FAIL), ("12-01-10", FAIL),
("2022-02-29", FAIL), ("2022-02-29", FAIL),
# readonly # readonly
*xfail(scenarios=[ ("2070-12-31", "2024-02-29", {"readonly": True, "current_value": "2024-02-29"}),
("2070-12-31", "2024-02-29", {"readonly": True, "default": "2024-02-29"}),
], reason="Should not be overwritten"),
] ]
# fmt: on # fmt: on
@ -965,9 +950,7 @@ class TestTime(BaseTest):
("23:1", FAIL), ("23:1", FAIL),
("23:005", FAIL), ("23:005", FAIL),
# readonly # readonly
*xfail(scenarios=[ ("00:00", "08:00", {"readonly": True, "current_value": "08:00"}),
("00:00", "08:00", {"readonly": True, "default": "08:00"}),
], reason="Should not be overwritten"),
] ]
# fmt: on # fmt: on
@ -991,9 +974,7 @@ class TestEmail(BaseTest):
*nones(None, "", output=""), *nones(None, "", output=""),
("\n Abc@example.tld ", "Abc@example.tld"), ("\n Abc@example.tld ", "Abc@example.tld"),
# readonly # readonly
*xfail(scenarios=[ ("Abc@example.tld", "admin@ynh.local", {"readonly": True, "current_value": "admin@ynh.local"}),
("Abc@example.tld", "admin@ynh.local", {"readonly": True, "default": "admin@ynh.local"}),
], reason="Should not be overwritten"),
# Next examples are from https://github.com/JoshData/python-email-validator/blob/main/tests/test_syntax.py # Next examples are from https://github.com/JoshData/python-email-validator/blob/main/tests/test_syntax.py
# valid email values # valid email values
@ -1106,9 +1087,7 @@ class TestWebPath(BaseTest):
("https://example.com/folder", "/https://example.com/folder") ("https://example.com/folder", "/https://example.com/folder")
], reason="Should fail or scheme+domain removed"), ], reason="Should fail or scheme+domain removed"),
# readonly # readonly
*xfail(scenarios=[ ("/overwrite", "/value", {"readonly": True, "current_value": "/value"}),
("/overwrite", "/value", {"readonly": True, "default": "/value"}),
], reason="Should not be overwritten"),
# FIXME should path have forbidden_chars? # FIXME should path have forbidden_chars?
] ]
# fmt: on # fmt: on
@ -1133,9 +1112,7 @@ class TestUrl(BaseTest):
*nones(None, "", output=""), *nones(None, "", output=""),
("http://some.org/folder/file.txt", "http://some.org/folder/file.txt"), ("http://some.org/folder/file.txt", "http://some.org/folder/file.txt"),
# readonly # readonly
*xfail(scenarios=[ ("https://overwrite.org", "https://example.org", {"readonly": True, "current_value": "https://example.org"}),
("https://overwrite.org", "https://example.org", {"readonly": True, "default": "https://example.org"}),
], reason="Should not be overwritten"),
# rest is taken from https://github.com/pydantic/pydantic/blob/main/tests/test_networks.py # rest is taken from https://github.com/pydantic/pydantic/blob/main/tests/test_networks.py
# valid # valid
*unchanged( *unchanged(
@ -1425,9 +1402,7 @@ class TestSelect(BaseTest):
] ]
}, },
# readonly # readonly
*xfail(scenarios=[ ("one", "two", {"readonly": True, "choices": ["one", "two"], "current_value": "two"}),
("one", "two", {"readonly": True, "choices": ["one", "two"], "default": "two"}),
], reason="Should not be overwritten"),
] ]
# fmt: on # fmt: on
@ -1475,9 +1450,7 @@ class TestTags(BaseTest):
*all_fails(*([t] for t in [False, True, -1, 0, 1, 1337, 13.37, [], ["one"], {}]), raw_option={"choices": [False, True, -1, 0, 1, 1337, 13.37, [], ["one"], {}]}), *all_fails(*([t] for t in [False, True, -1, 0, 1, 1337, 13.37, [], ["one"], {}]), raw_option={"choices": [False, True, -1, 0, 1, 1337, 13.37, [], ["one"], {}]}),
*all_fails(*([str(t)] for t in [False, True, -1, 0, 1, 1337, 13.37, [], ["one"], {}]), raw_option={"choices": [False, True, -1, 0, 1, 1337, 13.37, [], ["one"], {}]}), *all_fails(*([str(t)] for t in [False, True, -1, 0, 1, 1337, 13.37, [], ["one"], {}]), raw_option={"choices": [False, True, -1, 0, 1, 1337, 13.37, [], ["one"], {}]}),
# readonly # readonly
*xfail(scenarios=[ ("one", "one,two", {"readonly": True, "choices": ["one", "two"], "current_value": "one,two"}),
("one", "one,two", {"readonly": True, "choices": ["one", "two"], "default": "one,two"}),
], reason="Should not be overwritten"),
] ]
# fmt: on # fmt: on
@ -1525,9 +1498,7 @@ class TestDomain(BaseTest):
("doesnt_exist.pouet", FAIL, {}), ("doesnt_exist.pouet", FAIL, {}),
("fake.com", FAIL, {"choices": ["fake.com"]}), ("fake.com", FAIL, {"choices": ["fake.com"]}),
# readonly # readonly
*xpass(scenarios=[ (domains1[0], YunohostError, {"readonly": True}), # readonly is forbidden
(domains1[0], domains1[0], {"readonly": True}),
], reason="Should fail since readonly is forbidden"),
] ]
}, },
{ {
@ -1628,9 +1599,7 @@ class TestApp(BaseTest):
(installed_non_webapp["id"], installed_non_webapp["id"]), (installed_non_webapp["id"], installed_non_webapp["id"]),
(installed_non_webapp["id"], FAIL, {"filter": "is_webapp"}), (installed_non_webapp["id"], FAIL, {"filter": "is_webapp"}),
# readonly # readonly
*xpass(scenarios=[ (installed_non_webapp["id"], YunohostError, {"readonly": True}), # readonly is forbidden
(installed_non_webapp["id"], installed_non_webapp["id"], {"readonly": True}),
], reason="Should fail since readonly is forbidden"),
] ]
}, },
] ]
@ -1747,9 +1716,7 @@ class TestUser(BaseTest):
("", regular_username, {"default": regular_username}) ("", regular_username, {"default": regular_username})
], reason="Should throw 'no default allowed'"), ], reason="Should throw 'no default allowed'"),
# readonly # readonly
*xpass(scenarios=[ (admin_username, YunohostError, {"readonly": True}), # readonly is forbidden
(admin_username, admin_username, {"readonly": True}),
], reason="Should fail since readonly is forbidden"),
] ]
}, },
] ]
@ -1833,9 +1800,7 @@ class TestGroup(BaseTest):
("", "custom_group", {"default": "custom_group"}), ("", "custom_group", {"default": "custom_group"}),
], reason="Should throw 'default must be in (None, 'all_users', 'visitors', 'admins')"), ], reason="Should throw 'default must be in (None, 'all_users', 'visitors', 'admins')"),
# readonly # readonly
*xpass(scenarios=[ ("admins", YunohostError, {"readonly": True}), # readonly is forbidden
("admins", "admins", {"readonly": True}),
], reason="Should fail since readonly is forbidden"),
] ]
}, },
] ]
@ -1961,7 +1926,7 @@ def test_options_query_string():
) )
def _assert_correct_values(options, raw_options): def _assert_correct_values(options, raw_options):
form = {option.name: option.value for option in options} form = {option.id: option.value for option in options}
for k, v in results.items(): for k, v in results.items():
if k == "file_id": if k == "file_id":
@ -1993,11 +1958,26 @@ def test_question_string_default_type():
out = ask_questions_and_parse_answers(questions, answers)[0] out = ask_questions_and_parse_answers(questions, answers)[0]
assert out.name == "some_string" assert out.id == "some_string"
assert out.type == "string" assert out.type == "string"
assert out.value == "some_value" assert out.value == "some_value"
def test_option_default_type_with_choices_is_select():
questions = {
"some_choices": {"choices": ["a", "b"]},
# LEGACY (`choices` in option `string` used to be valid)
# make sure this result as a `select` option
"some_legacy": {"type": "string", "choices": ["a", "b"]},
}
answers = {"some_choices": "a", "some_legacy": "a"}
options = ask_questions_and_parse_answers(questions, answers)
for option in options:
assert option.type == "select"
assert option.value == "a"
@pytest.mark.skip # we should do something with this example @pytest.mark.skip # we should do something with this example
def test_question_string_input_test_ask_with_example(): def test_question_string_input_test_ask_with_example():
ask_text = "some question" ask_text = "some question"
@ -2018,75 +1998,6 @@ def test_question_string_input_test_ask_with_example():
assert example_text in prompt.call_args[1]["message"] assert example_text in prompt.call_args[1]["message"]
def test_question_string_with_choice():
questions = {"some_string": {"type": "string", "choices": ["fr", "en"]}}
answers = {"some_string": "fr"}
out = ask_questions_and_parse_answers(questions, answers)[0]
assert out.name == "some_string"
assert out.type == "string"
assert out.value == "fr"
def test_question_string_with_choice_prompt():
questions = {"some_string": {"type": "string", "choices": ["fr", "en"]}}
answers = {"some_string": "fr"}
with patch.object(Moulinette, "prompt", return_value="fr"), patch.object(
os, "isatty", return_value=True
):
out = ask_questions_and_parse_answers(questions, answers)[0]
assert out.name == "some_string"
assert out.type == "string"
assert out.value == "fr"
def test_question_string_with_choice_bad():
questions = {"some_string": {"type": "string", "choices": ["fr", "en"]}}
answers = {"some_string": "bad"}
with pytest.raises(YunohostError), patch.object(os, "isatty", return_value=False):
ask_questions_and_parse_answers(questions, answers)
def test_question_string_with_choice_ask():
ask_text = "some question"
choices = ["fr", "en", "es", "it", "ru"]
questions = {
"some_string": {
"ask": ask_text,
"choices": choices,
}
}
answers = {}
with patch.object(Moulinette, "prompt", return_value="ru") as prompt, patch.object(
os, "isatty", return_value=True
):
ask_questions_and_parse_answers(questions, answers)
assert ask_text in prompt.call_args[1]["message"]
for choice in choices:
assert choice in prompt.call_args[1]["message"]
def test_question_string_with_choice_default():
questions = {
"some_string": {
"type": "string",
"choices": ["fr", "en"],
"default": "en",
}
}
answers = {}
with patch.object(os, "isatty", return_value=False):
out = ask_questions_and_parse_answers(questions, answers)[0]
assert out.name == "some_string"
assert out.type == "string"
assert out.value == "en"
@pytest.mark.skip # we should do something with this example @pytest.mark.skip # we should do something with this example
def test_question_password_input_test_ask_with_example(): def test_question_password_input_test_ask_with_example():
ask_text = "some question" ask_text = "some question"

View file

@ -144,13 +144,14 @@ def _set_hostname(hostname, pretty_hostname=None):
logger.debug(out) logger.debug(out)
@is_unit_operation() @is_unit_operation(exclude=["dyndns_recovery_password", "password"])
def tools_postinstall( def tools_postinstall(
operation_logger, operation_logger,
domain, domain,
username, username,
fullname, fullname,
password, password,
dyndns_recovery_password=None,
ignore_dyndns=False, ignore_dyndns=False,
force_diskspace=False, force_diskspace=False,
overwrite_root_password=True, overwrite_root_password=True,
@ -203,9 +204,8 @@ def tools_postinstall(
assert_password_is_strong_enough("admin", password) assert_password_is_strong_enough("admin", password)
# If this is a nohost.me/noho.st, actually check for availability # If this is a nohost.me/noho.st, actually check for availability
if not ignore_dyndns and is_yunohost_dyndns_domain(domain): dyndns = not ignore_dyndns and is_yunohost_dyndns_domain(domain)
available = None if dyndns:
# Check if the domain is available... # Check if the domain is available...
try: try:
available = _dyndns_available(domain) available = _dyndns_available(domain)
@ -213,17 +213,12 @@ def tools_postinstall(
# connectivity or something. Assume that this domain isn't manageable # connectivity or something. Assume that this domain isn't manageable
# and inform the user that we could not contact the dyndns host server. # and inform the user that we could not contact the dyndns host server.
except Exception: except Exception:
logger.warning( raise YunohostValidationError(
m18n.n("dyndns_provider_unreachable", provider="dyndns.yunohost.org") "dyndns_provider_unreachable", provider="dyndns.yunohost.org"
) )
if available:
dyndns = True
# If not, abort the postinstall
else: else:
if not available:
raise YunohostValidationError("dyndns_unavailable", domain=domain) raise YunohostValidationError("dyndns_unavailable", domain=domain)
else:
dyndns = False
if os.system("iptables -V >/dev/null 2>/dev/null") != 0: if os.system("iptables -V >/dev/null 2>/dev/null") != 0:
raise YunohostValidationError( raise YunohostValidationError(
@ -235,7 +230,11 @@ def tools_postinstall(
logger.info(m18n.n("yunohost_installing")) logger.info(m18n.n("yunohost_installing"))
# New domain config # New domain config
domain_add(domain, dyndns) domain_add(
domain,
dyndns_recovery_password=dyndns_recovery_password,
ignore_dyndns=ignore_dyndns,
)
domain_main_domain(domain) domain_main_domain(domain)
# First user # First user

View file

@ -30,8 +30,11 @@ from moulinette.utils.log import getActionLogger
from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.utils.error import YunohostError, YunohostValidationError
from yunohost.utils.form import ( from yunohost.utils.form import (
OPTIONS, OPTIONS,
BaseChoicesOption,
BaseInputOption,
BaseOption, BaseOption,
FileOption, FileOption,
OptionType,
ask_questions_and_parse_answers, ask_questions_and_parse_answers,
evaluate_simple_js_expression, evaluate_simple_js_expression,
) )
@ -146,15 +149,17 @@ class ConfigPanel:
if mode == "full": if mode == "full":
option["ask"] = ask option["ask"] = ask
question_class = OPTIONS[option.get("type", "string")] question_class = OPTIONS[option.get("type", OptionType.string)]
# FIXME : maybe other properties should be taken from the question, not just choices ?. # FIXME : maybe other properties should be taken from the question, not just choices ?.
if issubclass(question_class, BaseChoicesOption):
option["choices"] = question_class(option).choices option["choices"] = question_class(option).choices
if issubclass(question_class, BaseInputOption):
option["default"] = question_class(option).default option["default"] = question_class(option).default
option["pattern"] = question_class(option).pattern option["pattern"] = question_class(option).pattern
else: else:
result[key] = {"ask": ask} result[key] = {"ask": ask}
if "current_value" in option: if "current_value" in option:
question_class = OPTIONS[option.get("type", "string")] question_class = OPTIONS[option.get("type", OptionType.string)]
result[key]["value"] = question_class.humanize( result[key]["value"] = question_class.humanize(
option["current_value"], option option["current_value"], option
) )
@ -239,7 +244,7 @@ class ConfigPanel:
self.filter_key = "" self.filter_key = ""
self._get_config_panel() self._get_config_panel()
for panel, section, option in self._iterate(): for panel, section, option in self._iterate():
if option["type"] == "button": if option["type"] == OptionType.button:
key = f"{panel['id']}.{section['id']}.{option['id']}" key = f"{panel['id']}.{section['id']}.{option['id']}"
actions[key] = _value_for_locale(option["ask"]) actions[key] = _value_for_locale(option["ask"])
@ -421,7 +426,7 @@ class ConfigPanel:
subnode["name"] = key # legacy subnode["name"] = key # legacy
subnode.setdefault("optional", raw_infos.get("optional", True)) subnode.setdefault("optional", raw_infos.get("optional", True))
# If this section contains at least one button, it becomes an "action" section # If this section contains at least one button, it becomes an "action" section
if subnode.get("type") == "button": if subnode.get("type") == OptionType.button:
out["is_action_section"] = True out["is_action_section"] = True
out.setdefault(sublevel, []).append(subnode) out.setdefault(sublevel, []).append(subnode)
# Key/value are a property # Key/value are a property
@ -465,20 +470,10 @@ class ConfigPanel:
"max_progression", "max_progression",
] ]
forbidden_keywords += format_description["sections"] forbidden_keywords += format_description["sections"]
forbidden_readonly_types = ["password", "app", "domain", "user", "file"]
for _, _, option in self._iterate(): for _, _, option in self._iterate():
if option["id"] in forbidden_keywords: if option["id"] in forbidden_keywords:
raise YunohostError("config_forbidden_keyword", keyword=option["id"]) raise YunohostError("config_forbidden_keyword", keyword=option["id"])
if (
option.get("readonly", False)
and option.get("type", "string") in forbidden_readonly_types
):
raise YunohostError(
"config_forbidden_readonly_type",
type=option["type"],
id=option["id"],
)
return self.config return self.config
@ -506,13 +501,13 @@ class ConfigPanel:
# Hydrating config panel with current value # Hydrating config panel with current value
for _, section, option in self._iterate(): for _, section, option in self._iterate():
if option["id"] not in self.values: if option["id"] not in self.values:
allowed_empty_types = [ allowed_empty_types = {
"alert", OptionType.alert,
"display_text", OptionType.display_text,
"markdown", OptionType.markdown,
"file", OptionType.file,
"button", OptionType.button,
] }
if section["is_action_section"] and option.get("default") is not None: if section["is_action_section"] and option.get("default") is not None:
self.values[option["id"]] = option["default"] self.values[option["id"]] = option["default"]
@ -526,7 +521,7 @@ class ConfigPanel:
f"Config panel question '{option['id']}' should be initialized with a value during install or upgrade.", f"Config panel question '{option['id']}' should be initialized with a value during install or upgrade.",
raw_msg=True, raw_msg=True,
) )
value = self.values[option["name"]] value = self.values[option["id"]]
# Allow to use value instead of current_value in app config script. # Allow to use value instead of current_value in app config script.
# e.g. apps may write `echo 'value: "foobar"'` in the config file (which is more intuitive that `echo 'current_value: "foobar"'` # e.g. apps may write `echo 'value: "foobar"'` in the config file (which is more intuitive that `echo 'current_value: "foobar"'`
@ -593,7 +588,7 @@ class ConfigPanel:
section["options"] = [ section["options"] = [
option option
for option in section["options"] for option in section["options"]
if option.get("type", "string") != "button" if option.get("type", OptionType.string) != OptionType.button
or option["id"] == action or option["id"] == action
] ]
@ -605,14 +600,14 @@ class ConfigPanel:
prefilled_answers.update(self.new_values) prefilled_answers.update(self.new_values)
questions = ask_questions_and_parse_answers( questions = ask_questions_and_parse_answers(
{question["name"]: question for question in section["options"]}, {question["id"]: question for question in section["options"]},
prefilled_answers=prefilled_answers, prefilled_answers=prefilled_answers,
current_values=self.values, current_values=self.values,
hooks=self.hooks, hooks=self.hooks,
) )
self.new_values.update( self.new_values.update(
{ {
question.name: question.value question.id: question.value
for question in questions for question in questions
if question.value is not None if question.value is not None
} }

File diff suppressed because it is too large Load diff

View file

@ -25,6 +25,7 @@ import subprocess
from typing import Dict, Any, List, Union from typing import Dict, Any, List, Union
from moulinette import m18n from moulinette import m18n
from moulinette.utils.text import random_ascii
from moulinette.utils.process import check_output from moulinette.utils.process import check_output
from moulinette.utils.log import getActionLogger from moulinette.utils.log import getActionLogger
from moulinette.utils.filesystem import mkdir, chown, chmod, write_to_file from moulinette.utils.filesystem import mkdir, chown, chmod, write_to_file
@ -679,6 +680,7 @@ class SystemuserAppResource(AppResource):
##### Properties ##### Properties
- `allow_ssh`: (default: False) Adds the user to the ssh.app group, allowing SSH connection via this user - `allow_ssh`: (default: False) Adds the user to the ssh.app group, allowing SSH connection via this user
- `allow_sftp`: (default: False) Adds the user to the sftp.app group, allowing SFTP connection via this user - `allow_sftp`: (default: False) Adds the user to the sftp.app group, allowing SFTP connection via this user
- `allow_email`: (default: False) Enable authentication on the mail stack for the system user and send mail using `__APP__@__DOMAIN__`. A `mail_pwd` setting is automatically defined (similar to `db_pwd` for databases). You can then configure the app to use `__APP__` and `__MAIL_PWD__` as SMTP credentials (with host 127.0.0.1). You can also tweak the user-part of the domain-part of the email used by manually defining a custom setting `mail_user` or `mail_domain`
- `home`: (default: `/var/www/__APP__`) Defines the home property for this user. NB: unfortunately you can't simply use `__INSTALL_DIR__` or `__DATA_DIR__` for now - `home`: (default: `/var/www/__APP__`) Defines the home property for this user. NB: unfortunately you can't simply use `__INSTALL_DIR__` or `__DATA_DIR__` for now
##### Provision/Update ##### Provision/Update
@ -702,6 +704,7 @@ class SystemuserAppResource(AppResource):
default_properties: Dict[str, Any] = { default_properties: Dict[str, Any] = {
"allow_ssh": False, "allow_ssh": False,
"allow_sftp": False, "allow_sftp": False,
"allow_email": False,
"home": "/var/www/__APP__", "home": "/var/www/__APP__",
} }
@ -709,9 +712,12 @@ class SystemuserAppResource(AppResource):
allow_ssh: bool = False allow_ssh: bool = False
allow_sftp: bool = False allow_sftp: bool = False
allow_email: bool = False
home: str = "" home: str = ""
def provision_or_update(self, context: Dict = {}): def provision_or_update(self, context: Dict = {}):
from yunohost.app import regen_mail_app_user_config_for_dovecot_and_postfix
# FIXME : validate that no yunohost user exists with that name? # FIXME : validate that no yunohost user exists with that name?
# and/or that no system user exists during install ? # and/or that no system user exists during install ?
@ -756,7 +762,31 @@ class SystemuserAppResource(AppResource):
f"sed -i 's@{raw_user_line_in_etc_passwd}@{new_raw_user_line_in_etc_passwd}@g' /etc/passwd" f"sed -i 's@{raw_user_line_in_etc_passwd}@{new_raw_user_line_in_etc_passwd}@g' /etc/passwd"
) )
# Update mail-related stuff
if self.allow_email:
mail_pwd = self.get_setting("mail_pwd")
if not mail_pwd:
mail_pwd = random_ascii(24)
self.set_setting("mail_pwd", mail_pwd)
regen_mail_app_user_config_for_dovecot_and_postfix()
else:
self.delete_setting("mail_pwd")
if (
os.system(
f"grep --quiet ' {self.app}$' /etc/postfix/app_senders_login_maps"
)
== 0
or os.system(
f"grep --quiet '^{self.app}:' /etc/dovecot/app-senders-passwd"
)
== 0
):
regen_mail_app_user_config_for_dovecot_and_postfix()
def deprovision(self, context: Dict = {}): def deprovision(self, context: Dict = {}):
from yunohost.app import regen_mail_app_user_config_for_dovecot_and_postfix
if os.system(f"getent passwd {self.app} >/dev/null 2>/dev/null") == 0: if os.system(f"getent passwd {self.app} >/dev/null 2>/dev/null") == 0:
os.system(f"deluser {self.app} >/dev/null") os.system(f"deluser {self.app} >/dev/null")
if os.system(f"getent passwd {self.app} >/dev/null 2>/dev/null") == 0: if os.system(f"getent passwd {self.app} >/dev/null 2>/dev/null") == 0:
@ -771,6 +801,17 @@ class SystemuserAppResource(AppResource):
f"Failed to delete system user for {self.app}", raw_msg=True f"Failed to delete system user for {self.app}", raw_msg=True
) )
self.delete_setting("mail_pwd")
if (
os.system(
f"grep --quiet ' {self.app}$' /etc/postfix/app_senders_login_maps"
)
== 0
or os.system(f"grep --quiet '^{self.app}:' /etc/dovecot/app-senders-passwd")
== 0
):
regen_mail_app_user_config_for_dovecot_and_postfix()
# FIXME : better logging and error handling, add stdout/stderr from the deluser/delgroup commands... # FIXME : better logging and error handling, add stdout/stderr from the deluser/delgroup commands...
@ -1315,8 +1356,6 @@ class DatabaseAppResource(AppResource):
self.set_setting("db_pwd", db_pwd) self.set_setting("db_pwd", db_pwd)
if not db_pwd: if not db_pwd:
from moulinette.utils.text import random_ascii
db_pwd = random_ascii(24) db_pwd = random_ascii(24)
self.set_setting("db_pwd", db_pwd) self.set_setting("db_pwd", db_pwd)