Merge remote-tracking branch 'origin/dev' into bookworm

This commit is contained in:
Alexandre Aubin 2024-07-15 16:54:21 +02:00
commit 262a3c5cf2
28 changed files with 409 additions and 137 deletions

24
debian/changelog vendored
View file

@ -4,6 +4,30 @@ yunohost (12.0.0) unstable; urgency=low
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 04 May 2023 20:30:19 +0200 -- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 04 May 2023 20:30:19 +0200
yunohost (11.2.21) stable; urgency=low
- log: optimize log list perf by creating a 'cache' symlink pointing to the log's parent ([#1907](http://github.com/YunoHost/yunohost/pull/1907))
- log: small hack when dumping log right after script failure, prevent a weird edge case where it'll dump the log of the resource provisioning instead of the script (1bb81e8f)
- debian: Bullseye->Bookworm migration ('hidden' but easier to test) ([#1759](http://github.com/YunoHost/yunohost/pull/1759), ab8e0e66, e54e99bf)
- helpers/apt: rely on simpler dpkg-deb --build rather than equivs to create .deb for app virtual dependencies (f6fbd69c, 8be726b9)
- helpers/apt: Support apt repositories with [trusted=yes] ([#1903](http://github.com/YunoHost/yunohost/pull/1903))
- backups: one should be able to restore a backup archive by providing a path to the archive without moving it to /home/yunohost.backup/archives/ (c8a18129, b266e398)
- backups: yunohost should not ask confirmation that 'YunoHost is already installed' when restoring only apps (9c22d36c)
- i18n: translate _diagnosis_ignore function ([#1894](http://github.com/YunoHost/yunohost/pull/1894))
- i18n: Translations updated for Basque, Catalan, French, Galician, German, Indonesian, Japanese, Russian, Spanish, Ukrainian
Thanks to all contributors <3 ! (alexAubin, Anonymous, cjdw, Félix Piédallu, Ivan Davydov, José M, Kayou, OniriCorpe, ppr, Zwiebel)
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 15 Jul 2024 16:22:26 +0200
yunohost (11.2.20.2) stable; urgency=low
- Fix service enable/disable auto-ignoring diagnosis entries ([#1886](http://github.com/YunoHost/yunohost/pull/1886))
Thanks to all contributors <3 ! (OniriCorpe)
-- Alexandre Aubin <alex.aubin@mailoo.org> Wed, 03 Jul 2024 21:51:50 +0200
yunohost (11.2.20.1) stable; urgency=low yunohost (11.2.20.1) stable; urgency=low
- helpers2.1: typo (1ed56952e) - helpers2.1: typo (1ed56952e)

4
debian/control vendored
View file

@ -18,7 +18,7 @@ Depends: python3-all (>= 3.11),
, python3-cryptography, python3-jwt, python3-passlib, python3-magic , python3-cryptography, python3-jwt, python3-passlib, python3-magic
, python-is-python3, python3-pydantic, python3-email-validator , python-is-python3, python3-pydantic, python3-email-validator
, nginx, nginx-extras (>=1.22) , nginx, nginx-extras (>=1.22)
, apt, apt-transport-https, apt-utils, dirmngr , apt, apt-transport-https, apt-utils, aptitude, dirmngr
, openssh-server, iptables, fail2ban, bind9-dnsutils , openssh-server, iptables, fail2ban, bind9-dnsutils
, openssl, ca-certificates, netcat-openbsd, iproute2 , openssl, ca-certificates, netcat-openbsd, iproute2
, slapd, ldap-utils, sudo-ldap, libnss-ldapd, unscd, libpam-ldapd , slapd, ldap-utils, sudo-ldap, libnss-ldapd, unscd, libpam-ldapd
@ -29,7 +29,7 @@ Depends: python3-all (>= 3.11),
, redis-server , redis-server
, acl , acl
, git, curl, wget, cron, unzip, jq, bc, at, procps, j2cli , git, curl, wget, cron, unzip, jq, bc, at, procps, j2cli
, lsb-release, haveged, fake-hwclock, equivs, lsof, whois , lsb-release, haveged, fake-hwclock, lsof, whois
Recommends: yunohost-admin, yunohost-portal (>= 12.0) Recommends: yunohost-admin, yunohost-portal (>= 12.0)
, ntp, inetutils-ping | iputils-ping , ntp, inetutils-ping | iputils-ping
, bash-completion, rsyslog , bash-completion, rsyslog

View file

@ -186,21 +186,21 @@ ynh_package_install_from_equivs() {
# Build and install the package # Build and install the package
local TMPDIR=$(mktemp --directory) local TMPDIR=$(mktemp --directory)
mkdir -p ${TMPDIR}/${pkgname}/DEBIAN/
# Make sure to delete the legacy compat file # For some reason, dpkg-deb insists for folder perm to be 755 and sometimes it's 777 o_O?
# It's now handle somewhat magically through the control file chmod -R 755 ${TMPDIR}/${pkgname}
rm -f /usr/share/equivs/template/debian/compat
# Note that the cd executes into a sub shell # Note that the cd executes into a sub shell
# Create a fake deb package with equivs-build and the given control file # Create a fake deb package with equivs-build and the given control file
# Install the fake package without its dependencies with dpkg # Install the fake package without its dependencies with dpkg
# Install missing dependencies with ynh_package_install # Install missing dependencies with ynh_package_install
ynh_wait_dpkg_free ynh_wait_dpkg_free
cp "$controlfile" "${TMPDIR}/control" cp "$controlfile" "${TMPDIR}/${pkgname}/DEBIAN/control"
( (
cd "$TMPDIR" cd "$TMPDIR"
LC_ALL=C equivs-build ./control 2>&1 # Install the fake package without its dependencies with dpkg --force-depends
LC_ALL=C dpkg --force-depends --install "./${pkgname}_${pkgversion}_all.deb" 2>&1 | tee ./dpkg_log LC_ALL=C dpkg-deb --build ${pkgname} ${pkgname}.deb > ./dpkg_log 2>&1 || { cat ./dpkg_log; false; }
LC_ALL=C dpkg --force-depends --install "./${pkgname}.deb" 2>&1 | tee ./dpkg_log
) )
ynh_package_install --fix-broken \ ynh_package_install --fix-broken \
@ -323,6 +323,7 @@ Package: ${dep_app}-ynh-deps
Version: ${version} Version: ${version}
Depends: ${dependencies} Depends: ${dependencies}
Architecture: all Architecture: all
Maintainer: root@localhost
Description: Fake package for ${app} (YunoHost app) dependencies Description: Fake package for ${app} (YunoHost app) dependencies
This meta-package is only responsible of installing its dependencies. This meta-package is only responsible of installing its dependencies.
EOF EOF
@ -470,21 +471,29 @@ ynh_install_extra_repo() {
wget_append="tee" wget_append="tee"
fi fi
# Split the repository into uri, suite and components. if [[ "$key" == "trusted=yes" ]]; then
trusted="--trusted"
else
trusted=""
fi
IFS=', ' read -r -a repo_parts <<< "$repo"
index=0
# Remove "deb " at the beginning of the repo. # Remove "deb " at the beginning of the repo.
repo="${repo#deb }" if [[ "${repo_parts[0]}" == "deb" ]]; then
index=1
# Get the uri fi
local uri="$(echo "$repo" | awk '{ print $1 }')" uri="${repo_parts[$index]}" ; index=$((index+1))
suite="${repo_parts[$index]}" ; index=$((index+1))
# Get the suite
local suite="$(echo "$repo" | awk '{ print $2 }')"
# Get the components # Get the components
local component="${repo##$uri $suite }" if (( "${#repo_parts[@]}" > 0 )); then
component="${repo_parts[*]:$index}"
fi
# Add the repository into sources.list.d # Add the repository into sources.list.d
ynh_add_repo --uri="$uri" --suite="$suite" --component="$component" --name="$name" $append ynh_add_repo --uri="$uri" --suite="$suite" --component="$component" --name="$name" $append $trusted
# Pin the new repo with the default priority, so it won't be used for upgrades. # Pin the new repo with the default priority, so it won't be used for upgrades.
# Build $pin from the uri without http and any sub path # Build $pin from the uri without http and any sub path
@ -497,7 +506,7 @@ ynh_install_extra_repo() {
ynh_pin_repo --package="*" --pin="origin \"$pin\"" $priority --name="$name" $append ynh_pin_repo --package="*" --pin="origin \"$pin\"" $priority --name="$name" $append
# Get the public key for the repo # Get the public key for the repo
if [ -n "$key" ]; then if [ -n "$key" ] && [[ "$key" != "trusted=yes" ]]; then
mkdir --parents "/etc/apt/trusted.gpg.d" mkdir --parents "/etc/apt/trusted.gpg.d"
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget) # Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor | $wget_append /etc/apt/trusted.gpg.d/$name.gpg >/dev/null wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor | $wget_append /etc/apt/trusted.gpg.d/$name.gpg >/dev/null
@ -550,6 +559,7 @@ ynh_remove_extra_repo() {
# | arg: -c, --component= - Component of the repository. # | arg: -c, --component= - Component of the repository.
# | arg: -n, --name= - Name for the files for this repo, $app as default value. # | arg: -n, --name= - Name for the files for this repo, $app as default value.
# | arg: -a, --append - Do not overwrite existing files. # | arg: -a, --append - Do not overwrite existing files.
# | arg: -t, --trusted - Add trusted=yes to the repository (not recommended)
# #
# Example for a repo like deb http://forge.yunohost.org/debian/ stretch stable # Example for a repo like deb http://forge.yunohost.org/debian/ stretch stable
# uri suite component # uri suite component
@ -558,13 +568,14 @@ ynh_remove_extra_repo() {
# Requires YunoHost version 3.8.1 or higher. # Requires YunoHost version 3.8.1 or higher.
ynh_add_repo() { ynh_add_repo() {
# Declare an array to define the options of this helper. # Declare an array to define the options of this helper.
local legacy_args=uscna local legacy_args=uscnat
local -A args_array=([u]=uri= [s]=suite= [c]=component= [n]=name= [a]=append) local -A args_array=([u]=uri= [s]=suite= [c]=component= [n]=name= [a]=append [t]=trusted)
local uri local uri
local suite local suite
local component local component
local name local name
local append local append
local trusted
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
name="${name:-$app}" name="${name:-$app}"
@ -575,10 +586,15 @@ ynh_add_repo() {
else else
append="tee" append="tee"
fi fi
if [[ "$trusted" -eq 1 ]]; then
trust="[trusted=yes]"
else
trust=""
fi
mkdir --parents "/etc/apt/sources.list.d" mkdir --parents "/etc/apt/sources.list.d"
# Add the new repo in sources.list.d # Add the new repo in sources.list.d
echo "deb $uri $suite $component" \ echo "deb $trust $uri $suite $component" \
| $append "/etc/apt/sources.list.d/$name.list" | $append "/etc/apt/sources.list.d/$name.list"
} }

View file

@ -90,27 +90,28 @@ ynh_apt_install_dependencies() {
dependencies="$current_dependencies, $dependencies" dependencies="$current_dependencies, $dependencies"
fi fi
# ############################# # ################
# Actual install using equivs # # Actual install #
# ############################# # ################
# Prepare the virtual-dependency control file for equivs # Prepare the virtual-dependency control file for dpkg-deb --build
local TMPDIR=$(mktemp --directory) local TMPDIR=$(mktemp --directory)
cat >${TMPDIR}/control <<EOF # Make a control file for equivs-build mkdir -p ${TMPDIR}/${app_ynh_deps}/DEBIAN
# For some reason, dpkg-deb insists for folder perm to be 755 and sometimes it's 777 o_O?
chmod -R 755 ${TMPDIR}/${app_ynh_deps}
cat >${TMPDIR}/${app_ynh_deps}/DEBIAN/control <<EOF
Section: misc Section: misc
Priority: optional Priority: optional
Package: ${app_ynh_deps} Package: ${app_ynh_deps}
Version: ${version} Version: ${version}
Depends: ${dependencies} Depends: ${dependencies}
Architecture: all Architecture: all
Maintainer: root@localhost
Description: Fake package for ${app} (YunoHost app) dependencies Description: Fake package for ${app} (YunoHost app) dependencies
This meta-package is only responsible of installing its dependencies. This meta-package is only responsible of installing its dependencies.
EOF EOF
# Make sure to delete equivs' legacy compat file
# It's now handle somewhat magically through the control file
rm -f /usr/share/equivs/template/debian/compat
_ynh_apt update _ynh_apt update
_ynh_wait_dpkg_free _ynh_wait_dpkg_free
@ -119,8 +120,8 @@ EOF
# NB: this is in a subshell (though not sure why exactly not just use pushd/popd...) # NB: this is in a subshell (though not sure why exactly not just use pushd/popd...)
cd "$TMPDIR" cd "$TMPDIR"
# Install the fake package without its dependencies with dpkg --force-depends # Install the fake package without its dependencies with dpkg --force-depends
LC_ALL=C equivs-build ./control > ./equivs_log 2>&1 || { cat ./equivs_log; false; } LC_ALL=C dpkg-deb --build ${app_ynh_deps} ${app_ynh_deps}.deb > ./dpkg_log 2>&1 || { cat ./dpkg_log; false; }
LC_ALL=C dpkg --force-depends --install "./${app_ynh_deps}_${version}_all.deb" > ./dpkg_log 2>&1 LC_ALL=C dpkg --force-depends --install "./${app_ynh_deps}.deb" > ./dpkg_log 2>&1
) )
# Then install the missing dependencies with apt install # Then install the missing dependencies with apt install
@ -198,14 +199,30 @@ ynh_apt_install_dependencies_from_extra_repository() {
# =========================================== # ===========================================
# Split the repository into uri, suite and components. # Split the repository into uri, suite and components.
repo="${repo#deb }" IFS=', ' read -r -a repo_parts <<< "$repo"
local uri="$(echo "$repo" | awk '{ print $1 }')" index=0
local suite="$(echo "$repo" | awk '{ print $2 }')"
local component="${repo##$uri $suite }" # Remove "deb " at the beginning of the repo.
if [[ "${repo_parts[0]}" == "deb" ]]; then
index=1
fi
uri="${repo_parts[$index]}" ; index=$((index+1))
suite="${repo_parts[$index]}" ; index=$((index+1))
# Get the components
if (( "${#repo_parts[@]}" > 0 )); then
component="${repo_parts[*]:$index}"
fi
if [[ "$key" == "trusted=yes" ]]; then
trust="[trusted=yes]"
else
trust=""
fi
# Add the new repo in sources.list.d # Add the new repo in sources.list.d
mkdir --parents "/etc/apt/sources.list.d" mkdir --parents "/etc/apt/sources.list.d"
echo "deb $uri $suite $component" > "/etc/apt/sources.list.d/$app.list" echo "deb $trust $uri $suite $component" > "/etc/apt/sources.list.d/$app.list"
# Pin the new repo with the default priority, so it won't be used for upgrades. # Pin the new repo with the default priority, so it won't be used for upgrades.
# Build $pin from the uri without http and any sub path # Build $pin from the uri without http and any sub path
@ -220,9 +237,11 @@ Pin: origin $pin
Pin-Priority: 995 Pin-Priority: 995
EOF EOF
if [ -n "$key" ] && [[ "$key" != "trusted=yes" ]]; then
mkdir --parents "/etc/apt/trusted.gpg.d" mkdir --parents "/etc/apt/trusted.gpg.d"
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget) # Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor > /etc/apt/trusted.gpg.d/$app.gpg wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor > /etc/apt/trusted.gpg.d/$app.gpg
fi
# Update the list of package with the new repo NB: we use -o # Update the list of package with the new repo NB: we use -o
# Dir::Etc::sourcelist to only refresh this repo, because # Dir::Etc::sourcelist to only refresh this repo, because

View file

@ -377,3 +377,82 @@ ynh_user_get_info() {
ynh_user_list() { ynh_user_list() {
yunohost user list --output-as json --quiet | jq -r ".users | keys[]" yunohost user list --output-as json --quiet | jq -r ".users | keys[]"
} }
# Spawn a Bash shell with the app environment loaded
#
# usage: ynh_spawn_app_shell "appname"
#
# examples:
# ynh_spawn_app_shell "foobar" <<< 'echo "$USER"'
# ynh_spawn_app_shell "foobar" < /tmp/some_script.bash
#
# The spawned shell will have environment variables loaded and environment files sourced
# from the app's service configuration file (defaults to $app.service, overridable by the packager with `service` setting).
# If the app relies on a specific PHP version, then `php` will be aliased that version. The PHP command will also be appended with the `phpflags` settings.
ynh_spawn_app_shell() {
local app=$1
# Force Bash to be used to run this helper
[[ $0 =~ \/?bash$ ]] || ynh_die "Please use Bash as shell"
# Make sure the app is installed
test -d /etc/yunohost/apps/$app || ynh_die "$app is not an installed app ?!"
# Make sure the app has its own user
id -u "$app" &>/dev/null || ynh_die "There is no \"$app\" system user"
# Make sure the app has an install_dir setting
local install_dir=$(ynh_app_setting_get --app=$app --key=install_dir)
[ -n "$install_dir" ] || ynh_die "$app has no install_dir setting (does it use packaging format >=2?)"
# Load the app's service name, or default to $app
local service=$(ynh_app_setting_get --app=$app --key=service)
[ -z "$service" ] && service=$app;
# Export HOME variable
export HOME=$install_dir;
# Load the Environment variables from the app's service
local env_var=$(systemctl show $service.service -p "Environment" --value)
[ -n "$env_var" ] && export $env_var;
# Force `php` to its intended version
# We use `eval`+`export` since `alias` is not propagated to subshells, even with `export`
local phpversion=$(ynh_app_setting_get --app=$app --key=phpversion)
local phpflags=$(ynh_app_setting_get --app=$app --key=phpflags)
if [ -n "$phpversion" ]
then
eval "php() { php${phpversion} ${phpflags} \"\$@\"; }"
export -f php
fi
# Source the EnvironmentFiles from the app's service
local env_files=($(systemctl show $service.service -p "EnvironmentFiles" --value))
if [ ${#env_files[*]} -gt 0 ]
then
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
set -a
for file in ${env_files[*]}
do
[[ $file = /* ]] && source $file
done
set +a
fi
# Activate the Python environment, if it exists
if [ -f $install_dir/venv/bin/activate ]
then
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
set -a
source $install_dir/venv/bin/activate
set +a
fi
# cd into the WorkingDirectory set in the service, or default to the install_dir
local env_dir=$(systemctl show $service.service -p "WorkingDirectory" --value)
[ -z $env_dir ] && env_dir=$install_dir;
cd $env_dir
# Spawn the app shell
su -s /bin/bash $app
}

View file

@ -63,7 +63,7 @@
"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": "Muss ein gültiger Dateiname mit maximal 30 Zeichen sein, ausschliesslich alphanumerische Zeichen und -_.", "pattern_backup_archive_name": "Muss ein gültiger Dateiname mit maximal 30 Zeichen sein, ausschließlich 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 (mindestens 3 Zeichen)", "pattern_firstname": "Muss ein gültiger Vorname sein (mindestens 3 Zeichen)",

View file

@ -239,6 +239,13 @@
"diagnosis_http_special_use_tld": "Domain {domain} is based on a special-use top-level domain (TLD) such as .local or .test and is therefore not expected to be exposed outside the local network.", "diagnosis_http_special_use_tld": "Domain {domain} is based on a special-use top-level domain (TLD) such as .local or .test and is therefore not expected to be exposed outside the local network.",
"diagnosis_http_timeout": "Timed-out while trying to contact your server from the outside. It appears to be unreachable.<br>1. The most common cause for this issue is that port 80 (and 443) <a href='https://yunohost.org/isp_box_config'>are not correctly forwarded to your server</a>.<br>2. You should also make sure that the service nginx is running<br>3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.", "diagnosis_http_timeout": "Timed-out while trying to contact your server from the outside. It appears to be unreachable.<br>1. The most common cause for this issue is that port 80 (and 443) <a href='https://yunohost.org/isp_box_config'>are not correctly forwarded to your server</a>.<br>2. You should also make sure that the service nginx is running<br>3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.",
"diagnosis_http_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network.", "diagnosis_http_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network.",
"diagnosis_ignore_already_filtered": "(There is already a diagnosis {category} filter with these criterias)",
"diagnosis_ignore_criteria_error": "Criterias should be of the form key=value (e.g. domain=yolo.test)",
"diagnosis_ignore_filter_added": "Added a {category} diagnosis filter",
"diagnosis_ignore_filter_removed": "Removed a {category} diagnosis filter",
"diagnosis_ignore_missing_criteria": "You should provide at least one criteria being the diagnosis category to ignore",
"diagnosis_ignore_no_filter_found": "(There is no such diagnosis {category} filter with these criterias to remove)",
"diagnosis_ignore_no_issue_found": "No issues was found matching the given criteria.",
"diagnosis_ignored_issues": "(+ {nb_ignored} ignored issue(s))", "diagnosis_ignored_issues": "(+ {nb_ignored} ignored issue(s))",
"diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason… Is a firewall blocking DNS requests?", "diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason… Is a firewall blocking DNS requests?",
"diagnosis_ip_broken_resolvconf": "Domain name resolution seems to be broken on your server, which seems related to <code>/etc/resolv.conf</code> not pointing to <code>127.0.0.1</code>.", "diagnosis_ip_broken_resolvconf": "Domain name resolution seems to be broken on your server, which seems related to <code>/etc/resolv.conf</code> not pointing to <code>127.0.0.1</code>.",
@ -571,16 +578,16 @@
"main_domain_changed": "The main domain has been changed", "main_domain_changed": "The main domain has been changed",
"migration_0027_cleaning_up": "Cleaning up cache and packages not useful anymore…", "migration_0027_cleaning_up": "Cleaning up cache and packages not useful anymore…",
"migration_0027_delayed_api_restart": "The YunoHost API will automatically be restarted in 15 seconds. It may be unavailable for a few seconds, and then you will have to login again.", "migration_0027_delayed_api_restart": "The YunoHost API will automatically be restarted in 15 seconds. It may be unavailable for a few seconds, and then you will have to login again.",
"migration_0027_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade.", "migration_0027_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade properly.",
"migration_0027_main_upgrade": "Starting main upgrade…", "migration_0027_main_upgrade": "Starting main upgrade…",
"migration_0027_modified_files": "Please note that the following files were found to be manually modified and might be overwritten following the upgrade: {manually_modified_files}", "migration_0027_modified_files": "Please note that the following files were found to be manually modified and might be overwritten following the upgrade: {manually_modified_files}",
"migration_0027_not_bullseye": "The current Debian distribution is not Bullseye! If you already ran the Bullseye->Bookworm migration, then this error is symptomatic of the fact that the migration procedure was not 100% succesful (otherwise YunoHost would have flagged it as completed). It is recommended to investigate what happened with the support team, who will need the **full** log of the `migration, which can be found in Tools > Logs in the webadmin.", "migration_0027_not_bullseye": "The current Debian distribution is not Bullseye! If you already ran the Bullseye -> Bookworm migration, then this error is symptomatic of the fact that the migration procedure was not 100% succesful (otherwise YunoHost would have flagged it as completed). It is recommended to investigate what happened with the support team, who will need the **full** log of the migration, which can be found in Tools > Logs in the webadmin.",
"migration_0027_not_enough_free_space": "Free space is pretty low in /var/! You should have at least 1GB free to run this migration.", "migration_0027_not_enough_free_space": "Free space is pretty low in /var/! You should have at least 1GB free to run this migration.",
"migration_0027_patch_yunohost_conflicts": "Applying patch to workaround conflict issue…", "migration_0027_patch_yunohost_conflicts": "Applying patch to workaround conflict issue…",
"migration_0027_patching_sources_list": "Patching the sources.lists…", "migration_0027_patching_sources_list": "Patching the sources.lists file…",
"migration_0027_problematic_apps_warning": "Please note that the following possibly problematic installed apps were detected. It looks like those were not installed from the YunoHost app catalog, or are not flagged as 'working'. Consequently, it cannot be guaranteed that they will still work after the upgrade: {problematic_apps}", "migration_0027_problematic_apps_warning": "Please note that the following possibly problematic installed apps were detected. It looks like those were not installed from the YunoHost app catalog, or are not flagged as 'working'. Consequently, it cannot be guaranteed that they will still work after the upgrade: {problematic_apps}",
"migration_0027_start": "Starting migration to Bullseye", "migration_0027_start": "Starting migration to Bookworm…",
"migration_0027_still_on_bullseye_after_main_upgrade": "Something went wrong during the main upgrade, the system appears to still be on Debian Bullseye", "migration_0027_still_on_bullseye_after_main_upgrade": "Something went wrong during the main upgrade, the system appears to still be on Debian Bullseye.",
"migration_0027_system_not_fully_up_to_date": "Your system is not fully up-to-date. Please perform a regular upgrade before running the migration to Bullseye.", "migration_0027_system_not_fully_up_to_date": "Your system is not fully up-to-date. Please perform a regular upgrade before running the migration to Bullseye.",
"migration_0027_yunohost_upgrade": "Starting YunoHost core upgrade…", "migration_0027_yunohost_upgrade": "Starting YunoHost core upgrade…",
"migration_0029_not_enough_space": "Make sufficient space available in {path} to run the migration.", "migration_0029_not_enough_space": "Make sufficient space available in {path} to run the migration.",

View file

@ -781,5 +781,27 @@
"log_dyndns_unsubscribe": "Se désabonner d'un sous-domaine YunoHost '{}'", "log_dyndns_unsubscribe": "Se désabonner d'un sous-domaine YunoHost '{}'",
"dyndns_too_many_requests": "Le service dyndns de YunoHost a reçu trop de requêtes/demandes de votre part, attendez environ 1 heure avant de réessayer.", "dyndns_too_many_requests": "Le service dyndns de YunoHost a reçu trop de requêtes/demandes de votre part, attendez environ 1 heure avant de réessayer.",
"ask_dyndns_recovery_password_explain_unavailable": "Ce domaine DynDNS est déjà enregistré. Si vous êtes la personne qui a enregistré ce domaine lors de sa création, vous pouvez entrer le mot de passe de récupération pour récupérer ce domaine.", "ask_dyndns_recovery_password_explain_unavailable": "Ce domaine DynDNS est déjà enregistré. Si vous êtes la personne qui a enregistré ce domaine lors de sa création, vous pouvez entrer le mot de passe de récupération pour récupérer ce domaine.",
"global_settings_setting_ssh_port_help": "Il est préférable d'utiliser un port inférieur à 1024 pour éviter les tentatives d'usurpation par des services non administrateurs sur la machine distante. Vous devez également éviter d'utiliser un port déjà utilisé tel que le 80 ou le 443." "global_settings_setting_ssh_port_help": "Il est préférable d'utiliser un port inférieur à 1024 pour éviter les tentatives d'usurpation par des services non administrateurs sur la machine distante. Vous devez également éviter d'utiliser un port déjà utilisé tel que le 80 ou le 443.",
"diagnosis_ignore_already_filtered": "(Il y a déjà un filtre de diagnostic {category} qui correspond à ces critères)",
"diagnosis_ignore_no_filter_found": "(Il n'y pas de filtre de diagnostic pour la catégorie {category} qui correspond à ces critères)",
"diagnosis_ignore_filter_added": "Filtre de diagnostic pour {category} ajouté",
"diagnosis_ignore_filter_removed": "Filtre de diagnostic pour {category} supprimé",
"diagnosis_ignore_missing_criteria": "Vous devez fournir au moins un critère qui est une catégorie de diagnostic à ignorer",
"diagnosis_ignore_criteria_error": "Les critères doivent être sous la forme de clé=valeur (ex. domain=yolo.test)",
"diagnosis_ignore_no_issue_found": "Aucun problème correspondant au critère donné n'a été trouvé.",
"migration_description_0027_migrate_to_bookworm": "Mettre à jour le système vers Debian Bookworm et YunoHost 12",
"migration_0027_delayed_api_restart": "L'API de YunoHost sera automatiquement redémarrée dans 15 secondes. Il se peut qu'elle soit indisponible pendant quelques secondes, après quoi vous devrez vous connecter à nouveau.",
"migration_0027_general_warning": "Veuillez noter que cette migration est une opération délicate. L'équipe de YunoHost a fait de son mieux pour l'examiner et la tester, mais la migration peut encore casser des parties du système ou de ses applications.\n\nPar conséquent, il est recommandé:\n - d'effectuer une sauvegarde de toutes les données ou applications critiques. Plus d'informations sur https://yunohost.org/backup;\n - de faire preuve de patience après avoir lancé la migration: en fonction de votre connexion Internet et de votre matériel, la mise à niveau peut prendre quelques heures pour s'effectuer correctement.",
"migration_0027_not_bullseye": "La distribution Debian actuelle n'est pas Bullseye! Si vous avez déjà effectué la migration Bullseye -> Bookworm, cette erreur est symptomatique du fait que la procédure de migration n'a pas réussi à 100 % (sinon YunoHost l'aurait marquée comme terminée). Il est recommandé de chercher ce qui s'est passé avec l'équipe de support, qui aura besoin du journal **complet** de la migration, qui peut être trouvé dans Outils > Journaux dans la webadmin.",
"migration_0027_cleaning_up": "Nettoyage du cache et des paquets qui ne sont plus utiles…",
"migration_0027_main_upgrade": "Démarrage de la mise à niveau du système…",
"migration_0027_modified_files": "Veuillez noter que les fichiers suivants ont été modifiés manuellement et pourraient être écrasés après la mise à niveau: {manually_modified_files}",
"migration_0027_not_enough_free_space": "L'espace libre est plutôt faible dans /var/! Vous devez disposer d'au moins 1 Go d'espace libre pour effectuer cette migration.",
"migration_0027_patch_yunohost_conflicts": "Application d'un correctif pour résoudre le problème de conflit…",
"migration_0027_patching_sources_list": "Correction du fichier sources.lists…",
"migration_0027_problematic_apps_warning": "Veuillez noter que des applications installées susceptibles de poser problème ont été détectées. Il semble qu'elles n'aient pas été installées à partir du catalogue d'applications de YunoHost, ou bien qu'elles ne soient pas marquées comme 'fonctionnelles'. Par conséquent, il ne peut pas être garanti qu'elles continueront à fonctionner après la mise à jour: {problematic_apps}",
"migration_0027_start": "Démarrage de la migration vers Bookworm…",
"migration_0027_still_on_bullseye_after_main_upgrade": "Quelque chose s'est mal passé lors de la mise à jour du système, il semble que celui-ci soit toujours sous Debian Bullseye.",
"migration_0027_system_not_fully_up_to_date": "Votre système n'est pas complètement à jour. Veuillez effectuer une mise à jour classique avant de procéder à la migration vers Bullseye.",
"migration_0027_yunohost_upgrade": "Démarrage de la mise à jour du cœur de YunoHost…"
} }

View file

@ -41,7 +41,7 @@
"apps_catalog_failed_to_download": "Non se puido descargar o catálogo de apps {apps_catalog}: {error}", "apps_catalog_failed_to_download": "Non se puido descargar o catálogo de apps {apps_catalog}: {error}",
"apps_catalog_updating": "Actualizando o catálogo de aplicacións…", "apps_catalog_updating": "Actualizando o catálogo de aplicacións…",
"apps_catalog_init_success": "Sistema do catálogo de apps iniciado!", "apps_catalog_init_success": "Sistema do catálogo de apps iniciado!",
"apps_already_up_to_date": "Xa tes tódalas apps ao día", "apps_already_up_to_date": "Xa tes todas as apps ao día",
"app_packaging_format_not_supported": "Esta app non se pode instalar porque o formato de empaquetado non está soportado pola túa versión de YunoHost. Deberías considerar actualizar o teu sistema.", "app_packaging_format_not_supported": "Esta app non se pode instalar porque o formato de empaquetado non está soportado pola túa versión de YunoHost. Deberías considerar actualizar o teu sistema.",
"app_upgraded": "{app} actualizadas", "app_upgraded": "{app} actualizadas",
"app_upgrade_some_app_failed": "Algunhas apps non se puideron actualizar", "app_upgrade_some_app_failed": "Algunhas apps non se puideron actualizar",
@ -317,7 +317,7 @@
"group_cannot_be_deleted": "O grupo {group} non se pode eliminar manualmente.", "group_cannot_be_deleted": "O grupo {group} non se pode eliminar manualmente.",
"group_cannot_edit_primary_group": "O grupo '{group}' non se pode editar manualmente. É o grupo primario que contén só a unha usuaria concreta.", "group_cannot_edit_primary_group": "O grupo '{group}' non se pode editar manualmente. É o grupo primario que contén só a unha usuaria concreta.",
"group_cannot_edit_visitors": "O grupo 'visitors' non se pode editar manualmente. É un grupo especial que representa a tódas visitantes anónimas", "group_cannot_edit_visitors": "O grupo 'visitors' non se pode editar manualmente. É un grupo especial que representa a tódas visitantes anónimas",
"group_cannot_edit_all_users": "O grupo 'all_users' non se pode editar manualmente. É un grupo especial que contén tódalas usuarias rexistradas en YunoHost", "group_cannot_edit_all_users": "O grupo 'all_users' non se pode editar manualmente. É un grupo especial que contén todas as usuarias rexistradas en YunoHost",
"disk_space_not_sufficient_update": "Non hai espazo suficiente no disco para actualizar esta aplicación", "disk_space_not_sufficient_update": "Non hai espazo suficiente no disco para actualizar esta aplicación",
"disk_space_not_sufficient_install": "Non queda espazo suficiente no disco para instalar esta aplicación", "disk_space_not_sufficient_install": "Non queda espazo suficiente no disco para instalar esta aplicación",
"log_help_to_get_log": "Para ver o rexistro completo da operación '{desc}', usa o comando 'yunohost log show {name}'", "log_help_to_get_log": "Para ver o rexistro completo da operación '{desc}', usa o comando 'yunohost log show {name}'",
@ -447,8 +447,8 @@
"permission_not_found": "Non se atopa o permiso '{permission}'", "permission_not_found": "Non se atopa o permiso '{permission}'",
"permission_deletion_failed": "Non se puido eliminar o permiso '{permission}': {error}", "permission_deletion_failed": "Non se puido eliminar o permiso '{permission}': {error}",
"permission_deleted": "O permiso '{permission}' foi eliminado", "permission_deleted": "O permiso '{permission}' foi eliminado",
"permission_cant_add_to_all_users": "O permiso {permission} non pode ser concecido a tódalas usuarias.", "permission_cant_add_to_all_users": "O permiso {permission} non se pode conceder a todas as usuarias.",
"permission_currently_allowed_for_all_users": "Este permiso está concedido actualmente a tódalas usuarias ademáis de a outros grupos. Probablemente queiras ben eliminar o permiso 'all_users' ou ben eliminar os outros grupos que teñen permiso.", "permission_currently_allowed_for_all_users": "Este permiso está concedido actualmente para todas as usuarias ademáis de a outros grupos. Probablemente queiras ben eliminar o permiso 'all_users' ou ben eliminar os outros grupos que teñen permiso.",
"restore_failed": "Non se puido restablecer o sistema", "restore_failed": "Non se puido restablecer o sistema",
"restore_extracting": "A extraer os ficheiros necesarios desde o arquivo…", "restore_extracting": "A extraer os ficheiros necesarios desde o arquivo…",
"restore_confirm_yunohost_installed": "Tes a certeza de querer restablecer un sistema xa instalado? [{answers}]", "restore_confirm_yunohost_installed": "Tes a certeza de querer restablecer un sistema xa instalado? [{answers}]",
@ -553,7 +553,7 @@
"service_removed": "Eliminado o servizo '{service}'", "service_removed": "Eliminado o servizo '{service}'",
"service_remove_failed": "Non se eliminou o servizo '{service}'", "service_remove_failed": "Non se eliminou o servizo '{service}'",
"service_enabled": "O servizo '{service}' vai ser iniciado automáticamente no inicio do sistema.", "service_enabled": "O servizo '{service}' vai ser iniciado automáticamente no inicio do sistema.",
"diagnosis_apps_allgood": "Tódalas apps instaladas respectan as prácticas básicas de empaquetado", "diagnosis_apps_allgood": "Todas as apps instaladas respectan as prácticas básicas de empaquetado",
"diagnosis_apps_bad_quality": "Esta aplicación está actualmente marcada como estragada no catálogo de aplicacións de YunoHost. Podería ser un problema temporal mentras as mantedoras intentan arranxar o problema. Ata ese momento a actualización desta app está desactivada.", "diagnosis_apps_bad_quality": "Esta aplicación está actualmente marcada como estragada no catálogo de aplicacións de YunoHost. Podería ser un problema temporal mentras as mantedoras intentan arranxar o problema. Ata ese momento a actualización desta app está desactivada.",
"log_user_import": "Importar usuarias", "log_user_import": "Importar usuarias",
"user_import_failed": "A operación de importación de usuarias fracasou", "user_import_failed": "A operación de importación de usuarias fracasou",
@ -664,7 +664,7 @@
"migration_0024_rebuild_python_venv_in_progress": "Intentando reconstruir o Python virtualenv para `{app}`", "migration_0024_rebuild_python_venv_in_progress": "Intentando reconstruir o Python virtualenv para `{app}`",
"migration_description_0024_rebuild_python_venv": "Reparar app Python após a migración a bullseye", "migration_description_0024_rebuild_python_venv": "Reparar app Python após a migración a bullseye",
"migration_0024_rebuild_python_venv_failed": "Fallou a reconstrución de Python virtualenv para {app}. A app podería non funcionar mentras non se resolve. Deberías intentar arranxar a situación forzando a actualización desta app usando `yunohost app upgrade --force {app}`.", "migration_0024_rebuild_python_venv_failed": "Fallou a reconstrución de Python virtualenv para {app}. A app podería non funcionar mentras non se resolve. Deberías intentar arranxar a situación forzando a actualización desta app usando `yunohost app upgrade --force {app}`.",
"migration_0021_not_buster2": "A distribución actual Debian non é Buster! Se xa realizaches a migración Buster->Bullseye entón este erro indica que o proceso de migración non se realizou de xeito correcto ao 100% (se non YunoHost debería telo marcado como completado). É recomendable comprobar xunto co equipo de axuda o que aconteceu, necesitarán o rexistro **completo** da `migración`, que podes atopar na webadmin en Ferramentas > Rexistros.", "migration_0021_not_buster2": "A distribución actual Debian non é Buster! Se xa realizaches a migración Buster -> Bullseye entón este erro indica que o proceso de migración non se realizou de xeito correcto ao 100% (se non YunoHost debería telo marcado como completado). É recomendable comprobar xunto co equipo de axuda o que aconteceu, necesitarán o rexistro **completo** da migración, que podes atopar na webadmin en Ferramentas > Rexistros.",
"global_settings_setting_admin_strength_help": "Estos requerimentos só se esixen ao inicializar ou cambiar o contrasinal", "global_settings_setting_admin_strength_help": "Estos requerimentos só se esixen ao inicializar ou cambiar o contrasinal",
"global_settings_setting_root_access_explain": "En sistemas Linux, 'root' é a administradora absoluta. No contexto YunoHost, o acceso SSH de 'root' está desactivado por defecto - excepto na rede local do servidor. Os compoñentes do grupo 'admins' poden utilizar o comando sudo para actuar como root desde a liña de comandos. É conveniente ter un contrasinal (forte) para root para xestionar o sistema por se as persoas administradoras perden o acceso por algún motivo.", "global_settings_setting_root_access_explain": "En sistemas Linux, 'root' é a administradora absoluta. No contexto YunoHost, o acceso SSH de 'root' está desactivado por defecto - excepto na rede local do servidor. Os compoñentes do grupo 'admins' poden utilizar o comando sudo para actuar como root desde a liña de comandos. É conveniente ter un contrasinal (forte) para root para xestionar o sistema por se as persoas administradoras perden o acceso por algún motivo.",
"migration_description_0025_global_settings_to_configpanel": "Migrar o nome antigo dos axustes globais aos novos nomes modernos", "migration_description_0025_global_settings_to_configpanel": "Migrar o nome antigo dos axustes globais aos novos nomes modernos",
@ -692,7 +692,7 @@
"log_settings_reset_all": "Restablecer todos os axustes", "log_settings_reset_all": "Restablecer todos os axustes",
"log_settings_set": "Aplicar axustes", "log_settings_set": "Aplicar axustes",
"admins": "Admins", "admins": "Admins",
"all_users": "Tódalas usuarias de YunoHost", "all_users": "Usuarias de YunoHost",
"app_action_failed": "Fallou a execución da acción {action} da app {app}", "app_action_failed": "Fallou a execución da acción {action} da app {app}",
"app_manifest_install_ask_init_admin_permission": "Quen debería ter acceso de administración a esta app? (Pode cambiarse despois)", "app_manifest_install_ask_init_admin_permission": "Quen debería ter acceso de administración a esta app? (Pode cambiarse despois)",
"app_manifest_install_ask_init_main_permission": "Quen debería ter acceso a esta app? (Pode cambiarse despois)", "app_manifest_install_ask_init_main_permission": "Quen debería ter acceso a esta app? (Pode cambiarse despois)",
@ -781,5 +781,27 @@
"log_dyndns_unsubscribe": "Retirar subscrición para o subdominio YunoHost '{}'", "log_dyndns_unsubscribe": "Retirar subscrición para o subdominio YunoHost '{}'",
"ask_dyndns_recovery_password_explain_unavailable": "Este dominio DynDNS xa está rexistrado. Se es a persoa que o rexistrou orixinalmente, podes escribir o código de recuperación para reclamar o dominio.", "ask_dyndns_recovery_password_explain_unavailable": "Este dominio DynDNS xa está rexistrado. Se es a persoa que o rexistrou orixinalmente, podes escribir o código de recuperación para reclamar o dominio.",
"dyndns_too_many_requests": "O servicio dyndns de YunoHost recibeu demasiadas peticións do teu sistema, agarda 1 hora e volve intentalo.", "dyndns_too_many_requests": "O servicio dyndns de YunoHost recibeu demasiadas peticións do teu sistema, agarda 1 hora e volve intentalo.",
"global_settings_setting_ssh_port_help": "É recomendable un porto inferior a 1024 para evitar os intentos de apropiación por parte de servizos de non-administración na máquina remota. Tamén deberías evitar elexir un porto que xa está sendo utilizado, como 80 ou 443." "global_settings_setting_ssh_port_help": "É recomendable un porto inferior a 1024 para evitar os intentos de apropiación por parte de servizos de non-administración na máquina remota. Tamén deberías evitar elexir un porto que xa está sendo utilizado, como 80 ou 443.",
"diagnosis_ignore_criteria_error": "Os criterios deben ter o formato key=value (ex. domain=yolo.test)",
"diagnosis_ignore_already_filtered": "(Xa existe un filtro de diagnóstico de {category} con estes criterios)",
"diagnosis_ignore_filter_removed": "Eliminouse o filtro do diagnóstico para {category}",
"diagnosis_ignore_no_filter_found": "(Non hai tal filtro do diagnóstico de {category} con este criterio a eliminar)",
"diagnosis_ignore_no_issue_found": "Non se atoparon incidencias para o criterio establecido.",
"diagnosis_ignore_filter_added": "Engadiuse o filtro do diagnóstico para {category}",
"diagnosis_ignore_missing_criteria": "Deberías proporcionar cando menos un criterio que a categoría de diagnóstico omitirá",
"migration_0027_start": "A iniciar a migración a Bookworm…",
"migration_0027_still_on_bullseye_after_main_upgrade": "Algo fallou durante a actualización principal, o sistema parece que aínda está en Debian Bullseye.",
"migration_0027_patching_sources_list": "A configurar o ficheiro sources.list…",
"migration_0027_general_warning": "Ten en conta que a migración é unha operación comprometida. O equipo de YunoHost intentou deseñala o mellor posible e probala, aínda así a migración podería estragar partes do sistema ou as aplicacións.\n\nAsí, é recomendable:\n - Facer unha copia de apoio dos datos críticos ou aplicacións. Máis info en https://yunohost.org/backup;\n - Ter pacencia unha vez iniciada a migración: en función da túa conexión a Internet e hardware podería levarlle varias horas completar todo o procedemento.",
"migration_0027_yunohost_upgrade": "A iniciar a actualización do núcleo de YunoHost…",
"migration_0027_not_bullseye": "A distribución Debian actual non é Bullseye! Se xa realizaches a migración Bullseye -> Bookworm este erro é síntoma de que o procedemento de migración non foi exitoso ao 100% (doutro xeito YunoHost teríao marcado como completado). É recomendable que investigues o que aconteceu, informando ao equipo de axuda que precisará o rexistro **completo** da migración, pódelo atopar na web de administración en Ferramentas -> Rexistros.",
"migration_0027_problematic_apps_warning": "Ten en conta que se atoparon as seguintes apps que poderían ser problemáticas. Semella que non foron instaladas desde o catálogo de aplicacións de YunoHost, ou non están marcadas como que 'funcionan'. Como consecuencia non podemos garantir que seguirán funcionando ben unha vez conclúa a migración: {problematic_apps}",
"migration_description_0027_migrate_to_bookworm": "Actualiza o sistema a Debian Bookworm e YunoHost 12",
"migration_0027_cleaning_up": "Limpando a caché e os paquetes que xa non son necesarios…",
"migration_0027_delayed_api_restart": "A API de YunoHost vaise reiniciar automaticamente en 15 segundos. Durante uns segundos non poderás usala, e despois terás que iniciar sesión outra vez.",
"migration_0027_main_upgrade": "A iniciar a actualización principal…",
"migration_0027_modified_files": "Detectamos que os seguintes ficheiros semella foron modificados manualmente e poderían ser sobreescritos durante a actualización: {manually_modified_files}",
"migration_0027_not_enough_free_space": "Hai moi pouco espazo en /var/! Deberías ter polo menos 1GB libre para realizar a migración.",
"migration_0027_patch_yunohost_conflicts": "Aplicando a solución para resolver o problema conflictivo…",
"migration_0027_system_not_fully_up_to_date": "O teu sistema non está totalmente actualizado. Fai unha actualización corrente antes de iniciar a migración a Bullseye."
} }

View file

@ -16,7 +16,7 @@
"app_manifest_install_ask_domain": "Pilih di domain mana aplikasi ini harus dipasang", "app_manifest_install_ask_domain": "Pilih di domain mana aplikasi ini harus dipasang",
"app_not_installed": "Tidak dapat menemukan {app} di daftar aplikasi yang terpasang: {all_apps}", "app_not_installed": "Tidak dapat menemukan {app} di daftar aplikasi yang terpasang: {all_apps}",
"app_not_properly_removed": "{app} belum dilepas dengan benar", "app_not_properly_removed": "{app} belum dilepas dengan benar",
"app_remove_after_failed_install": "Melepas aplikasi setelah kegagalan pemasangan…", "app_remove_after_failed_install": "Menyingkirkan aplikasi setelah kegagalan pemasangan…",
"app_removed": "{app} dilepas", "app_removed": "{app} dilepas",
"app_restore_failed": "Tidak dapat memulihkan {app}: {error}", "app_restore_failed": "Tidak dapat memulihkan {app}: {error}",
"app_upgrade_some_app_failed": "Beberapa aplikasi tidak dapat diperbarui", "app_upgrade_some_app_failed": "Beberapa aplikasi tidak dapat diperbarui",
@ -32,14 +32,14 @@
"app_unknown": "Aplikasi tak dikenal", "app_unknown": "Aplikasi tak dikenal",
"ask_new_admin_password": "Kata sandi administrasi baru", "ask_new_admin_password": "Kata sandi administrasi baru",
"ask_password": "Kata sandi", "ask_password": "Kata sandi",
"app_upgrade_app_name": "Memperbarui {app}…", "app_upgrade_app_name": "Sedang meningkatkan {app}…",
"app_upgrade_failed": "Tidak dapat memperbarui {app}: {error}", "app_upgrade_failed": "Tidak dapat memperbarui {app}: {error}",
"app_start_install": "Memasang {app}…", "app_start_install": "Memasang {app}…",
"app_start_remove": "Melepas {app}…", "app_start_remove": "Menyingkirkan {app}…",
"app_manifest_install_ask_password": "Pilih kata sandi administrasi untuk aplikasi ini", "app_manifest_install_ask_password": "Pilih kata sandi administrasi untuk aplikasi ini",
"app_upgrade_several_apps": "Aplikasi berikut akan diperbarui: {apps}", "app_upgrade_several_apps": "Aplikasi berikut akan diperbarui: {apps}",
"backup_app_failed": "Tidak dapat mencadangkan {app}", "backup_app_failed": "Tidak dapat mencadangkan {app}",
"backup_archive_name_exists": "Arsip cadangan dengan nama ini sudah ada.", "backup_archive_name_exists": "Arsip cadangan dengan nama '{name}' ini sudah ada.",
"backup_created": "Cadangan dibuat: {name}", "backup_created": "Cadangan dibuat: {name}",
"backup_creation_failed": "Tidak dapat membuat arsip cadangan", "backup_creation_failed": "Tidak dapat membuat arsip cadangan",
"backup_delete_error": "Tidak dapat menghapus '{path}'", "backup_delete_error": "Tidak dapat menghapus '{path}'",
@ -70,18 +70,18 @@
"app_not_enough_ram": "Aplikasi ini memerlukan {required} RAM untuk pemasangan/pembaruan, tapi sekarang hanya tersedia {current} saja.", "app_not_enough_ram": "Aplikasi ini memerlukan {required} RAM untuk pemasangan/pembaruan, tapi sekarang hanya tersedia {current} saja.",
"app_packaging_format_not_supported": "Aplikasi ini tidak dapat dipasang karena format pengemasan tidak didukung oleh YunoHost versi Anda. Anda sebaiknya memperbarui sistem Anda.", "app_packaging_format_not_supported": "Aplikasi ini tidak dapat dipasang karena format pengemasan tidak didukung oleh YunoHost versi Anda. Anda sebaiknya memperbarui sistem Anda.",
"ask_admin_username": "Nama pengguna admin", "ask_admin_username": "Nama pengguna admin",
"backup_archive_broken_link": "Tidak dapat mengakses arsip cadangan (tautan rusak untuk {path})", "backup_archive_broken_link": "Tidak dapat mengakses arsip cadangan (tautan rusak pada {path})",
"backup_archive_open_failed": "Tidak dapat membuka arsip cadangan", "backup_archive_open_failed": "Tidak dapat membuka arsip cadangan",
"certmanager_cert_install_success_selfsigned": "Sertifikat ditandai sendiri sekarang terpasang untuk '{domain}'", "certmanager_cert_install_success_selfsigned": "Sertifikat ditandai sendiri sekarang terpasang untuk '{domain}'",
"certmanager_cert_renew_failed": "Pembaruan ulang sertifikat Let's Encrypt gagal untuk {domains}", "certmanager_cert_renew_failed": "Pembaruan ulang sertifikat Let's Encrypt gagal untuk {domains}",
"certmanager_cert_renew_success": "Sertifikat Let's Encrypt diperbarui untuk domain '{domain}'", "certmanager_cert_renew_success": "Sertifikat Let's Encrypt diperbarui untuk domain '{domain}'",
"diagnosis_apps_allgood": "Semua aplikasi yang dipasang mengikuti panduan penyusunan yang baik", "diagnosis_apps_allgood": "Semua aplikasi yang dipasang mengikuti panduan pemaketan yang baik",
"diagnosis_basesystem_kernel": "Peladen memakai kernel Linux {kernel_version}", "diagnosis_basesystem_kernel": "Peladen memakai kernel Linux {kernel_version}",
"diagnosis_cache_still_valid": "(Tembolok masih valid untuk diagnosis {category}. Belum akan didiagnosis ulang!)", "diagnosis_cache_still_valid": "(Tembolok masih valid untuk diagnosis {category}. Belum akan didiagnosis ulang!)",
"diagnosis_description_dnsrecords": "Rekaman DNS", "diagnosis_description_dnsrecords": "Rekaman DNS",
"diagnosis_description_ip": "Konektivitas internet", "diagnosis_description_ip": "Konektivitas internet",
"diagnosis_description_web": "Web", "diagnosis_description_web": "Web",
"diagnosis_domain_expiration_error": "Beberapa domain akan kedaluwarsa SEGERA!", "diagnosis_domain_expiration_error": "Beberapa domain akan SEGERA kedaluwarsa!",
"diagnosis_domain_expiration_not_found_details": "Informasi WHOIS untuk domain {domain} sepertinya tidak mengandung informasi tentang tanggal kedaluwarsa?", "diagnosis_domain_expiration_not_found_details": "Informasi WHOIS untuk domain {domain} sepertinya tidak mengandung informasi tentang tanggal kedaluwarsa?",
"diagnosis_domain_expiration_warning": "Beberapa domain akan kedaluwarsa!", "diagnosis_domain_expiration_warning": "Beberapa domain akan kedaluwarsa!",
"diagnosis_domain_expires_in": "{domain} kedaluwarsa dalam {days} hari.", "diagnosis_domain_expires_in": "{domain} kedaluwarsa dalam {days} hari.",
@ -145,12 +145,12 @@
"user_import_bad_file": "Berkas CSV Anda tidak secara benar diformat, akan diabaikan untuk menghindari potensi data hilang", "user_import_bad_file": "Berkas CSV Anda tidak secara benar diformat, akan diabaikan untuk menghindari potensi data hilang",
"yunohost_postinstall_end_tip": "Proses pasca-pemasangan sudah selesai! Untuk menyelesaikan pengaturan Anda, pertimbangkan:\n - diagnosis masalah yang mungkin lewat bagian 'Diagnosis' di webadmin (atau 'yunohost diagnosis run' di cmd);\n - baca bagian 'Finalizing your setup' dan 'Getting to know YunoHost' di dokumentasi admin: https://yunohost.org/admindoc.", "yunohost_postinstall_end_tip": "Proses pasca-pemasangan sudah selesai! Untuk menyelesaikan pengaturan Anda, pertimbangkan:\n - diagnosis masalah yang mungkin lewat bagian 'Diagnosis' di webadmin (atau 'yunohost diagnosis run' di cmd);\n - baca bagian 'Finalizing your setup' dan 'Getting to know YunoHost' di dokumentasi admin: https://yunohost.org/admindoc.",
"app_already_installed_cant_change_url": "Aplikasi ini sudah terpasang. URL tidak dapat diubah hanya dengan ini. Periksa `app changeurl` jika tersedia.", "app_already_installed_cant_change_url": "Aplikasi ini sudah terpasang. URL tidak dapat diubah hanya dengan ini. Periksa `app changeurl` jika tersedia.",
"app_requirements_checking": "Memeriksa persyaratan untuk {app}…", "app_requirements_checking": "Memeriksa persyaratan pada {app}…",
"backup_create_size_estimation": "Arsip ini akan mengandung data dengan ukuran {size}.", "backup_create_size_estimation": "Arsip ini akan mengandung data dengan ukuran {size}.",
"certmanager_certificate_fetching_or_enabling_failed": "Mencoba untuk menggunakan sertifikat baru untuk {domain} tidak bisa…", "certmanager_certificate_fetching_or_enabling_failed": "Mencoba sertifikat baru pada {domain} tidak dapat digunakan…",
"certmanager_no_cert_file": "Tidak dapat membuka berkas sertifikat untuk domain {domain} (berkas: {file})", "certmanager_no_cert_file": "Tidak dapat membuka berkas sertifikat untuk domain {domain} (berkas: {file})",
"diagnosis_basesystem_hardware": "Arsitektur perangkat keras peladen adalah {virt} {arch}", "diagnosis_basesystem_hardware": "Arsitektur perangkat keras peladen adalah {virt} {arch}",
"diagnosis_basesystem_ynh_inconsistent_versions": "Anda menjalankan versi paket YunoHost yang tidak konsisten… sepertinya karena pembaruan yang gagal.", "diagnosis_basesystem_ynh_inconsistent_versions": "Anda menjalankan versi paket YunoHost yang tidak konsisten… sepertinya karena kegagalan atau sebagian pembaruan.",
"diagnosis_basesystem_ynh_single_version": "versi {package}: {version} ({repo})", "diagnosis_basesystem_ynh_single_version": "versi {package}: {version} ({repo})",
"diagnosis_description_services": "Status layanan", "diagnosis_description_services": "Status layanan",
"diagnosis_description_systemresources": "Sumber daya sistem", "diagnosis_description_systemresources": "Sumber daya sistem",
@ -186,7 +186,7 @@
"diagnosis_basesystem_host": "Peladen memakai Debian {debian_version}", "diagnosis_basesystem_host": "Peladen memakai Debian {debian_version}",
"diagnosis_domain_expiration_not_found": "Tidak dapat memeriksa tanggal kedaluwarsa untuk beberapa domain", "diagnosis_domain_expiration_not_found": "Tidak dapat memeriksa tanggal kedaluwarsa untuk beberapa domain",
"diagnosis_http_could_not_diagnose_details": "Galat: {error}", "diagnosis_http_could_not_diagnose_details": "Galat: {error}",
"app_manifest_install_ask_path": "Pilih jalur URL (setelah domain) dimana aplikasi ini akan dipasang", "app_manifest_install_ask_path": "Pilih jalur URL (setelah domain) dimana aplikasi ini harus dipasang",
"certmanager_cert_signing_failed": "Tidak dapat memverifikasi sertifikat baru", "certmanager_cert_signing_failed": "Tidak dapat memverifikasi sertifikat baru",
"config_validate_url": "Harus URL web yang valid", "config_validate_url": "Harus URL web yang valid",
"diagnosis_description_ports": "Penyingkapan porta", "diagnosis_description_ports": "Penyingkapan porta",
@ -211,7 +211,7 @@
"yunohost_configured": "YunoHost sudah terkonfigurasi", "yunohost_configured": "YunoHost sudah terkonfigurasi",
"global_settings_setting_pop3_enabled": "Aktifkan POP3", "global_settings_setting_pop3_enabled": "Aktifkan POP3",
"log_user_import": "Mengimpor pengguna", "log_user_import": "Mengimpor pengguna",
"app_start_backup": "Mengumpulkan berkas untuk dicadangkan untuk {app}…", "app_start_backup": "Mengumpulkan berkas untuk dicadangkan pada {app}…",
"app_upgrade_script_failed": "Galat terjadi di skrip pembaruan aplikasi", "app_upgrade_script_failed": "Galat terjadi di skrip pembaruan aplikasi",
"backup_csv_creation_failed": "Tidak dapat membuat berkas CSV yang dibutuhkan untuk pemulihan", "backup_csv_creation_failed": "Tidak dapat membuat berkas CSV yang dibutuhkan untuk pemulihan",
"certmanager_attempt_to_renew_valid_cert": "Sertifikat untuk domain '{domain}' belum akan kedaluwarsa! (Anda bisa menggunakan --force jika Anda tahu apa yang Anda lakukan)", "certmanager_attempt_to_renew_valid_cert": "Sertifikat untuk domain '{domain}' belum akan kedaluwarsa! (Anda bisa menggunakan --force jika Anda tahu apa yang Anda lakukan)",
@ -220,7 +220,7 @@
"upgrade_complete": "Pembaruan selesai", "upgrade_complete": "Pembaruan selesai",
"upgrading_packages": "Memperbarui paket…", "upgrading_packages": "Memperbarui paket…",
"diagnosis_description_apps": "Aplikasi", "diagnosis_description_apps": "Aplikasi",
"diagnosis_description_basesystem": "Basis sistem", "diagnosis_description_basesystem": "Sistem basis",
"global_settings_setting_pop3_enabled_help": "Aktifkan protokol POP3 untuk peladen surel", "global_settings_setting_pop3_enabled_help": "Aktifkan protokol POP3 untuk peladen surel",
"password_confirmation_not_the_same": "Kata sandi dan untuk konfirmasinya tidak sama", "password_confirmation_not_the_same": "Kata sandi dan untuk konfirmasinya tidak sama",
"restore_complete": "Pemulihan selesai", "restore_complete": "Pemulihan selesai",
@ -234,7 +234,7 @@
"app_sources_fetch_failed": "Tidak dapat mengambil berkas sumber, apakah URL-nya benar?", "app_sources_fetch_failed": "Tidak dapat mengambil berkas sumber, apakah URL-nya benar?",
"installation_complete": "Pemasangan selesai", "installation_complete": "Pemasangan selesai",
"app_arch_not_supported": "Aplikasi ini hanya bisa dipasang pada arsitektur {required}, tapi arsitektur peladen Anda adalah {current}", "app_arch_not_supported": "Aplikasi ini hanya bisa dipasang pada arsitektur {required}, tapi arsitektur peladen Anda adalah {current}",
"diagnosis_basesystem_hardware_model": "Model peladen adalah {model}", "diagnosis_basesystem_hardware_model": "Model server adalah {model}",
"app_yunohost_version_not_supported": "Aplikasi ini memerlukan YunoHost >= {required}, tapi versi yang terpasang adalah {current}", "app_yunohost_version_not_supported": "Aplikasi ini memerlukan YunoHost >= {required}, tapi versi yang terpasang adalah {current}",
"ask_new_path": "Jalur baru", "ask_new_path": "Jalur baru",
"backup_cleaning_failed": "Tidak dapat menghapus folder cadangan sementara", "backup_cleaning_failed": "Tidak dapat menghapus folder cadangan sementara",
@ -252,7 +252,7 @@
"config_validate_email": "Harus surel yang valid", "config_validate_email": "Harus surel yang valid",
"config_apply_failed": "Gagal menerapkan konfigurasi baru: {error}", "config_apply_failed": "Gagal menerapkan konfigurasi baru: {error}",
"diagnosis_basesystem_ynh_main_version": "Peladen memakai YunoHost {main_version} ({repo})", "diagnosis_basesystem_ynh_main_version": "Peladen memakai YunoHost {main_version} ({repo})",
"diagnosis_cant_run_because_of_dep": "Tidak dapat menjalankan diagnosis untuk {category} ketika ada masalah utama yang terkait dengan {dep}.", "diagnosis_cant_run_because_of_dep": "Tidak dapat menjalankan diagnosis pada {category} ketika ada masalah utama yang terkait dengan {dep}.",
"diagnosis_services_conf_broken": "Konfigurasi rusak untuk layanan {service}!", "diagnosis_services_conf_broken": "Konfigurasi rusak untuk layanan {service}!",
"diagnosis_services_running": "Layanan {service} berjalan!", "diagnosis_services_running": "Layanan {service} berjalan!",
"diagnosis_swap_ok": "Sistem ini memiliki {total} swap!", "diagnosis_swap_ok": "Sistem ini memiliki {total} swap!",
@ -296,7 +296,7 @@
"upnp_disabled": "UPnP dimatikan", "upnp_disabled": "UPnP dimatikan",
"global_settings_setting_smtp_allow_ipv6_help": "Perbolehkan penggunaan IPv6 untuk menerima dan mengirim surel", "global_settings_setting_smtp_allow_ipv6_help": "Perbolehkan penggunaan IPv6 untuk menerima dan mengirim surel",
"domain_config_default_app": "Aplikasi baku", "domain_config_default_app": "Aplikasi baku",
"diagnosis_diskusage_verylow": "Penyimpanan <code>{mountpoint}</code> (di perangkat <code>{device}</code>) hanya tinggal memiliki {free} ({free_percent}%) ruang kosong yang tersedia (dari {total}). Direkomendasikan untuk membersihkan ruang penyimpanan!", "diagnosis_diskusage_verylow": "Penyimpanan <code>{mountpoint}</code> (di perangkat <code>{device}</code>) hanya memiliki {free} ({free_percent}%) ruang kosong yang tersedia (dari {total}). Sebaiknya Anda mempertimbangkan untuk membersihkan ruang penyimpanan!",
"domain_config_api_protocol": "Protokol API", "domain_config_api_protocol": "Protokol API",
"domain_config_cert_summary_letsencrypt": "Bagus! Anda menggunakan sertifikat Let's Encrypt yang valid!", "domain_config_cert_summary_letsencrypt": "Bagus! Anda menggunakan sertifikat Let's Encrypt yang valid!",
"domain_config_mail_out": "Surel keluar", "domain_config_mail_out": "Surel keluar",
@ -329,7 +329,7 @@
"permission_require_account": "Izin {permission} hanya masuk akal untuk pengguna yang memiliki akun, maka ini tidak dapat diaktifkan untuk pengunjung.", "permission_require_account": "Izin {permission} hanya masuk akal untuk pengguna yang memiliki akun, maka ini tidak dapat diaktifkan untuk pengunjung.",
"permission_update_failed": "Tidak dapat memperbarui izin '{permission}': {error}", "permission_update_failed": "Tidak dapat memperbarui izin '{permission}': {error}",
"apps_failed_to_upgrade": "Aplikasi berikut gagal untuk diperbarui:{apps}", "apps_failed_to_upgrade": "Aplikasi berikut gagal untuk diperbarui:{apps}",
"backup_archive_name_unknown": "Arsip cadangan lokal tidak diketahui yang bernama '{name}'", "backup_archive_name_unknown": "Arsip cadangan lokal dengan nama '{name}' tidak diketahui",
"diagnosis_http_nginx_conf_not_up_to_date_details": "Untuk memperbaiki ini, periksa perbedaannya dari CLI menggunakan <cmd>yunohost tools regen-conf nginx --dry-run --with-diff</cmd> dan jika Anda sudah, terapkan perubahannya menggunakan <cmd>yunohost tools regen-conf nginx --force</cmd>.", "diagnosis_http_nginx_conf_not_up_to_date_details": "Untuk memperbaiki ini, periksa perbedaannya dari CLI menggunakan <cmd>yunohost tools regen-conf nginx --dry-run --with-diff</cmd> dan jika Anda sudah, terapkan perubahannya menggunakan <cmd>yunohost tools regen-conf nginx --force</cmd>.",
"domain_config_auth_token": "Token autentikasi", "domain_config_auth_token": "Token autentikasi",
"domain_config_cert_install": "Pasang sertifikat Let's Encrypt", "domain_config_cert_install": "Pasang sertifikat Let's Encrypt",
@ -351,7 +351,7 @@
"regenconf_now_managed_by_yunohost": "Berkas konfigurasi '{conf}' sekarang dikelola oleh YunoHost (kategori {category}).", "regenconf_now_managed_by_yunohost": "Berkas konfigurasi '{conf}' sekarang dikelola oleh YunoHost (kategori {category}).",
"regenconf_updated": "Konfigurasi diperbarui untuk '{category}'", "regenconf_updated": "Konfigurasi diperbarui untuk '{category}'",
"log_user_group_delete": "Menghapus kelompok '{}'", "log_user_group_delete": "Menghapus kelompok '{}'",
"backup_archive_cant_retrieve_info_json": "Tidak dapat memuat info untuk arsip '{archive}'… Berkas info.json tidak dapat didapakan (atau bukan json yang valid).", "backup_archive_cant_retrieve_info_json": "Tidak dapat memuat info pada arsip '{archive}'… Berkas info.json tidak dapat dipulihkan (atau bukan json yang valid).",
"diagnosis_mail_blacklist_reason": "Alasan pendaftarhitaman adalah: {reason}", "diagnosis_mail_blacklist_reason": "Alasan pendaftarhitaman adalah: {reason}",
"diagnosis_ports_unreachable": "Porta {port} tidak tercapai dari luar.", "diagnosis_ports_unreachable": "Porta {port} tidak tercapai dari luar.",
"diagnosis_ram_verylow": "Sistem hanya memiliki {available} ({available_percent}%) RAM yang tersedia! (dari {total})", "diagnosis_ram_verylow": "Sistem hanya memiliki {available} ({available_percent}%) RAM yang tersedia! (dari {total})",
@ -366,7 +366,7 @@
"log_permission_create": "Membuat izin '{}'", "log_permission_create": "Membuat izin '{}'",
"log_permission_delete": "Menghapus izin '{}'", "log_permission_delete": "Menghapus izin '{}'",
"backup_with_no_backup_script_for_app": "Aplikasi '{app}' tidak memiliki skrip pencadangan. Mengabaikan.", "backup_with_no_backup_script_for_app": "Aplikasi '{app}' tidak memiliki skrip pencadangan. Mengabaikan.",
"backup_system_part_failed": "Tidak dapat mencadangkan bagian '{part}' sistem", "backup_system_part_failed": "Tidak dapat mencadangkan bagian sistem '{part}'",
"log_user_create": "Menambahkan pengguna '{}'", "log_user_create": "Menambahkan pengguna '{}'",
"log_user_delete": "Menghapus pengguna '{}'", "log_user_delete": "Menghapus pengguna '{}'",
"log_user_group_create": "Membuat kelompok '{}'", "log_user_group_create": "Membuat kelompok '{}'",
@ -377,7 +377,7 @@
"diagnosis_dns_point_to_doc": "Silakan periksa dokumentasi di <a href='https://yunohost.org/dns_config'>https://yunohost.org/dns_config</a> jika Anda masih membutuhkan bantuan untuk mengatur rekaman DNS.", "diagnosis_dns_point_to_doc": "Silakan periksa dokumentasi di <a href='https://yunohost.org/dns_config'>https://yunohost.org/dns_config</a> jika Anda masih membutuhkan bantuan untuk mengatur rekaman DNS.",
"diagnosis_regenconf_manually_modified": "Berkas konfigurasi <code>{file}</code> sepertinya telah diubah manual.", "diagnosis_regenconf_manually_modified": "Berkas konfigurasi <code>{file}</code> sepertinya telah diubah manual.",
"backup_with_no_restore_script_for_app": "{app} tidak memiliki skrip pemulihan, Anda tidak akan bisa secara otomatis memulihkan cadangan aplikasi ini.", "backup_with_no_restore_script_for_app": "{app} tidak memiliki skrip pemulihan, Anda tidak akan bisa secara otomatis memulihkan cadangan aplikasi ini.",
"config_no_panel": "Tidak dapat menemukan panel konfigurasi.", "config_no_panel": "Panel konfigurasi tidak ditemukan.",
"confirm_app_install_warning": "Peringatan: Aplikasi ini mungkin masih bisa bekerja, tapi tidak terintegrasi dengan baik dengan YunoHost. Beberapa fitur seperti SSO dan pencadangan mungkin tidak tersedia. Tetap pasang? [{answers}] ", "confirm_app_install_warning": "Peringatan: Aplikasi ini mungkin masih bisa bekerja, tapi tidak terintegrasi dengan baik dengan YunoHost. Beberapa fitur seperti SSO dan pencadangan mungkin tidak tersedia. Tetap pasang? [{answers}] ",
"diagnosis_ports_ok": "Porta {port} tercapai dari luar.", "diagnosis_ports_ok": "Porta {port} tercapai dari luar.",
"diagnosis_ports_partially_unreachable": "Porta {port} tidak tercapai dari luar lewat IPv{failed}.", "diagnosis_ports_partially_unreachable": "Porta {port} tidak tercapai dari luar lewat IPv{failed}.",
@ -440,5 +440,16 @@
"restore_system_part_failed": "Tidak dapat memulihkan segmen '{part}'", "restore_system_part_failed": "Tidak dapat memulihkan segmen '{part}'",
"service_enable_failed": "Tidak dapat membuat layanan '{service}' dimulai mandiri saat pemulaian.\n\nLog layanan baru-baru ini:{logs}", "service_enable_failed": "Tidak dapat membuat layanan '{service}' dimulai mandiri saat pemulaian.\n\nLog layanan baru-baru ini:{logs}",
"service_not_reloading_because_conf_broken": "Tidak memuat atau memulai ulang layanan '{name}' karena konfigurasinya rusak: {errors}", "service_not_reloading_because_conf_broken": "Tidak memuat atau memulai ulang layanan '{name}' karena konfigurasinya rusak: {errors}",
"service_reloaded": "Layanan {service} dimuat ulang" "service_reloaded": "Layanan {service} dimuat ulang",
"additional_urls_already_removed": "URL tambahan '{url}' sudah disingkirkan pada URL tambahan untuk perizinan '{permission}'",
"additional_urls_already_added": "URL tambahan '{url}' sudah ditambahkan pada URL tambahan untuk perizinan '{permission}'",
"app_argument_password_no_default": "Galat ketika mengurai argumen sandi '{name}': argumen sandi tidak diperbolehkan mempunyai suatu nilai baku demi alasan keamanan",
"app_corrupt_source": "YunoHost telah berhasil mengunduh aset tersebut '{source_id}' ({url}) untuk {app}, tetapi aset tidak sesuai dengan checksum. Hal ini bisa jadi karena beberapa jaringan temporer mengalami kegagalan pada peladen Anda, ATAU entah bagaimana aset mengalami perubahan oleh penyelenggara hulu (atau pelakon jahat?) dan pemaket YunoHost perlu untuk menyelidiki dan mungkin pembaruan manifes applikasi tersebut untuk mempertimbangkan perubahan ini.\n\tEkspektasi checksum sha256: {expected_sha256}\n\tUnduhan checksum sha256: {computed_sha256}\n\tUnduhan ukuran berkas: {size}",
"app_not_upgraded_broken_system": "Aplikasi '{failed_app}' telah gagal meningkatkan dan menyebabkan sistem dalam status rusak, dan sebagai konsekuensi terhadap peningkatan aplikasi tersebut telah dibatalkan: {apps}",
"app_resource_failed": "Menyediakan, membatalkan penyediaan, atau memperbarui sumber daya pada {app} telah gagal: {error}",
"app_failed_to_download_asset": "Gagal mengunduh aset '{source_id}' ({url}) untuk {app}: {out}",
"apps_catalog_init_success": "Inisialisasi sistem katalog aplikasi!",
"app_unsupported_remote_type": "Tidak mendukung type remot yang digunakan pada aplikasi",
"app_not_upgraded_broken_system_continue": "Aplikasi '{failed_app}' telah gagal meningkatkan dan menyebabkan sistem dalam status rusak (jadi --continue-on-failure diabaikan), dan sebagai konsekuensi terhadap peningkatan aplikasi tersebut telah dibatalkan: {apps}",
"apps_failed_to_upgrade_line": "\n * {app_id}(untuk melihat log yang berkaitan lakukan 'yunohost log show {operation_logger_name}')"
} }

View file

@ -328,5 +328,17 @@
"global_settings_setting_smtp_allow_ipv6_help": "Разрешить использование IPv6 для получения и отправки почты", "global_settings_setting_smtp_allow_ipv6_help": "Разрешить использование IPv6 для получения и отправки почты",
"admins": "Администраторы", "admins": "Администраторы",
"all_users": "Все пользователи YunoHost", "all_users": "Все пользователи YunoHost",
"app_action_failed": "Не удалось выполнить действие {action} для приложения {app}" "app_action_failed": "Не удалось выполнить действие {action} для приложения {app}",
"app_manifest_install_ask_init_main_permission": "Кто должен иметь доступ к этому приложению? (Это может быть изменено позже)",
"app_arch_not_supported": "Это приложение может быть установлено только на архитектуры {required}, но архитектура вашего сервер - {current}",
"app_manifest_install_ask_init_admin_permission": "Кто должен иметь доступ к функциям для администраторов этого приложения? (Это может быть изменено позже)",
"app_change_url_script_failed": "Произошла ошибка внутри скрипта смены URL",
"app_corrupt_source": "YunoHost смог скачать материал «{source_id}» ({url}) для {app}, но материал не соотвествует с ожидаемой контрольной суммой. Это может означать, что на ваше сервере произошла временная сетевая ошибка, ИЛИ материал был каким-либо образом изменён сопровождающим главной ветки (или злоумышленником?) и упаковщикам YunoHost нужно выяснить и, возможно, обновить манифест, чтобы применить изменения.\n Ожидаемая контрольная сумма sha256: {expected_sha256}\n Полученная контрольная сумма sha256: {computed_sha256}\n Размер скачанного файла: {size}",
"app_not_enough_ram": "Это приложение требует {required} ОЗУ для установки/обновления, но сейчас доступно только {current}.",
"app_change_url_failed": "Невозможно изменить URL для {app}: {error}",
"app_not_enough_disk": "Это приложение требует {required} свободного места.",
"app_change_url_require_full_domain": "{app} не может быть перемещено на данный URL, потому что оно требует весь домен (т.е., путь - /)",
"app_failed_to_download_asset": "Не удалось скачать материал «{source_id}» ({url}) для {app}: {out}",
"app_failed_to_upgrade_but_continue": "Не удалось обновить приложение {failed_app}, обновления продолжаются, как запрошено. Выполните «yunohost log show {operation_logger_name}», чтобы увидеть журнал ошибки",
"app_not_upgraded_broken_system": "Не удалось обновить приложение «{failed_app}», система находится в сломанном состоянии, обновления следующих приложений были отменены: {apps}"
} }

View file

@ -32,6 +32,7 @@ def find_expected_string_keys():
python_files = glob.glob(ROOT + "src/*.py") python_files = glob.glob(ROOT + "src/*.py")
python_files.extend(glob.glob(ROOT + "src/utils/*.py")) python_files.extend(glob.glob(ROOT + "src/utils/*.py"))
python_files.extend(glob.glob(ROOT + "src/migrations/*.py")) python_files.extend(glob.glob(ROOT + "src/migrations/*.py"))
python_files.extend(glob.glob(ROOT + "src/migrations/*.py.disabled"))
python_files.extend(glob.glob(ROOT + "src/authenticators/*.py")) python_files.extend(glob.glob(ROOT + "src/authenticators/*.py"))
python_files.extend(glob.glob(ROOT + "src/diagnosers/*.py")) python_files.extend(glob.glob(ROOT + "src/diagnosers/*.py"))
python_files.append(ROOT + "bin/yunohost") python_files.append(ROOT + "bin/yunohost")
@ -75,6 +76,9 @@ def find_expected_string_keys():
continue continue
yield "migration_description_" + os.path.basename(path)[:-3] yield "migration_description_" + os.path.basename(path)[:-3]
# FIXME: to be removed in bookworm branch
yield "migration_description_0027_migrate_to_bookworm"
# For each default service, expect to find "service_description_<name>" # For each default service, expect to find "service_description_<name>"
for service, info in yaml.safe_load( for service, info in yaml.safe_load(
open(ROOT + "conf/yunohost/services.yml") open(ROOT + "conf/yunohost/services.yml")

View file

@ -1116,7 +1116,7 @@ backup:
api: PUT /backups/<name>/restore api: PUT /backups/<name>/restore
arguments: arguments:
name: name:
help: Name of the local backup archive help: Name or path of the backup archive
--system: --system:
help: List of system parts to restore (or all if none is given) help: List of system parts to restore (or all if none is given)
nargs: "*" nargs: "*"
@ -1147,7 +1147,7 @@ backup:
api: GET /backups/<name> api: GET /backups/<name>
arguments: arguments:
name: name:
help: Name of the local backup archive help: Name or path of the backup archive
-d: -d:
full: --with-details full: --with-details
help: Show additional backup information help: Show additional backup information

View file

@ -1881,6 +1881,10 @@ class TarBackupMethod(BackupMethod):
@property @property
def _archive_file(self): def _archive_file(self):
from yunohost.settings import settings_get from yunohost.settings import settings_get
if isinstance(self.manager, RestoreManager):
return self.manager.archive_path
if isinstance(self.manager, BackupManager) and settings_get( if isinstance(self.manager, BackupManager) and settings_get(
"misc.backup.backup_compress_tar_archives" "misc.backup.backup_compress_tar_archives"
): ):
@ -2272,11 +2276,6 @@ def backup_restore(name, system=[], apps=[], force=False):
# Initialize # # Initialize #
# #
if name.endswith(".tar.gz"):
name = name[: -len(".tar.gz")]
elif name.endswith(".tar"):
name = name[: -len(".tar")]
restore_manager = RestoreManager(name) restore_manager = RestoreManager(name)
restore_manager.set_system_targets(system) restore_manager.set_system_targets(system)
@ -2288,8 +2287,10 @@ def backup_restore(name, system=[], apps=[], force=False):
# Add validation if restoring system parts on an already-installed system # Add validation if restoring system parts on an already-installed system
# #
if restore_manager.targets.targets["system"] != [] and os.path.isfile( if (
"/etc/yunohost/installed" restore_manager.info["system"] != {}
and restore_manager.targets.targets["system"] != []
and os.path.isfile("/etc/yunohost/installed")
): ):
logger.warning(m18n.n("yunohost_already_installed")) logger.warning(m18n.n("yunohost_already_installed"))
if not force: if not force:
@ -2409,6 +2410,7 @@ def backup_info(name, with_details=False, human_readable=False):
human_readable -- Print sizes in human readable format human_readable -- Print sizes in human readable format
""" """
original_name = name
if name.endswith(".tar.gz"): if name.endswith(".tar.gz"):
name = name[: -len(".tar.gz")] name = name[: -len(".tar.gz")]
@ -2420,6 +2422,9 @@ def backup_info(name, with_details=False, human_readable=False):
# Check file exist (even if it's a broken symlink) # Check file exist (even if it's a broken symlink)
if not os.path.lexists(archive_file): if not os.path.lexists(archive_file):
archive_file += ".gz" archive_file += ".gz"
if not os.path.lexists(archive_file):
# Maybe the user provided a path to the backup?
archive_file = original_name
if not os.path.lexists(archive_file): if not os.path.lexists(archive_file):
raise YunohostValidationError("backup_archive_name_unknown", name=name) raise YunohostValidationError("backup_archive_name_unknown", name=name)

View file

@ -263,16 +263,12 @@ def _diagnosis_ignore(add_filter=None, remove_filter=None, list=False):
# Sanity checks for the provided arguments # Sanity checks for the provided arguments
if len(filter_) == 0: if len(filter_) == 0:
raise YunohostValidationError( raise YunohostValidationError(m18n.n("diagnosis_ignore_missing_criteria"))
"You should provide at least one criteria being the diagnosis category to ignore"
)
category = filter_[0] category = filter_[0]
if category not in all_categories_names: if category not in all_categories_names:
raise YunohostValidationError(f"{category} is not a diagnosis category") raise YunohostValidationError(f"{category} is not a diagnosis category")
if any("=" not in criteria for criteria in filter_[1:]): if any("=" not in criteria for criteria in filter_[1:]):
raise YunohostValidationError( raise YunohostValidationError(m18n.n("diagnosis_ignore_criteria_error"))
"Criterias should be of the form key=value (e.g. domain=yolo.test)"
)
# Convert the provided criteria into a nice dict # Convert the provided criteria into a nice dict
criterias = {c.split("=")[0]: c.split("=")[1] for c in filter_[1:]} criterias = {c.split("=")[0]: c.split("=")[1] for c in filter_[1:]}
@ -295,7 +291,7 @@ def _diagnosis_ignore(add_filter=None, remove_filter=None, list=False):
issue_matches_criterias(i, criterias) issue_matches_criterias(i, criterias)
for i in current_issues_for_this_category for i in current_issues_for_this_category
): ):
raise YunohostError("No issues was found matching the given criteria.") raise YunohostError(m18n.n("diagnosis_ignore_no_issue_found"))
# Make sure the subdicts/lists exists # Make sure the subdicts/lists exists
if "ignore_filters" not in configuration: if "ignore_filters" not in configuration:
@ -305,13 +301,13 @@ def _diagnosis_ignore(add_filter=None, remove_filter=None, list=False):
if criterias in configuration["ignore_filters"][category]: if criterias in configuration["ignore_filters"][category]:
logger.warning( logger.warning(
f"(There is already a diagnosis {category} filter with these criterias)" m18n.n("diagnosis_ignore_already_filtered", category=category)
) )
return return
configuration["ignore_filters"][category].append(criterias) configuration["ignore_filters"][category].append(criterias)
_diagnosis_write_configuration(configuration) _diagnosis_write_configuration(configuration)
logger.success(f"Added a {category} diagnosis filter") logger.success(m18n.n("diagnosis_ignore_filter_added", category=category))
return return
if remove_filter: if remove_filter:
@ -325,13 +321,13 @@ def _diagnosis_ignore(add_filter=None, remove_filter=None, list=False):
if criterias not in configuration["ignore_filters"][category]: if criterias not in configuration["ignore_filters"][category]:
logger.warning( logger.warning(
f"(There is no such diagnosis {category} filter with these criterias to remove)" m18n.n("diagnosis_ignore_no_filter_found", category=category)
) )
return return
configuration["ignore_filters"][category].remove(criterias) configuration["ignore_filters"][category].remove(criterias)
_diagnosis_write_configuration(configuration) _diagnosis_write_configuration(configuration)
logger.success(f"Removed a {category} diagnosis filter") logger.success(m18n.n("diagnosis_ignore_filter_removed", category=category))
return return

View file

@ -21,6 +21,7 @@ import re
import yaml import yaml
import glob import glob
import psutil import psutil
import time
from typing import List from typing import List
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -79,6 +80,39 @@ BORING_LOG_LINES = [
] ]
def _update_log_parent_symlinks():
one_year_ago = time.time() - 365 * 24 * 3600
logs = glob.iglob(OPERATIONS_PATH + "*" + METADATA_FILE_EXT)
for log_md in logs:
if os.path.getctime(log_md) < one_year_ago:
# Let's ignore files older than one year because hmpf reading a shitload of yml is not free
continue
name = log_md[: -len(METADATA_FILE_EXT)]
parent_symlink = os.path.join(OPERATIONS_PATH, f".{name}.parent.yml")
if os.path.islink(parent_symlink):
continue
try:
metadata = (
read_yaml(log_md) or {}
) # Making sure this is a dict and not None..?
except Exception as e:
# If we can't read the yaml for some reason, report an error and ignore this entry...
logger.error(m18n.n("log_corrupted_md_file", md_file=log_md, error=e))
continue
parent = metadata.get("parent")
parent = parent + METADATA_FILE_EXT if parent else "/dev/null"
try:
print(parent, parent_symlink)
os.symlink(parent, parent_symlink)
except Exception as e:
logger.warning(f"Failed to create symlink {parent_symlink} ? {e}")
def log_list(limit=None, with_details=False, with_suboperations=False): def log_list(limit=None, with_details=False, with_suboperations=False):
""" """
List available logs List available logs
@ -95,30 +129,43 @@ def log_list(limit=None, with_details=False, with_suboperations=False):
operations = {} operations = {}
logs = [x for x in os.listdir(OPERATIONS_PATH) if x.endswith(METADATA_FILE_EXT)] _update_log_parent_symlinks()
one_year_ago = time.time() - 365 * 24 * 3600
logs = [
x
for x in os.listdir(OPERATIONS_PATH)
if x.endswith(METADATA_FILE_EXT) and os.path.getctime(x) > one_year_ago
]
logs = list(reversed(sorted(logs))) logs = list(reversed(sorted(logs)))
if not with_suboperations:
def parent_symlink_points_to_dev_null(log):
name = log[: -len(METADATA_FILE_EXT)]
parent_symlink = os.path.join(OPERATIONS_PATH, f".{name}.parent.yml")
return (
os.path.islink(parent_symlink)
and os.path.realpath(parent_symlink) == "/dev/null"
)
logs = [log for log in logs if parent_symlink_points_to_dev_null(log)]
if limit is not None: if limit is not None:
if with_suboperations:
logs = logs[:limit] logs = logs[:limit]
else:
# If we displaying only parent, we are still gonna load up to limit * 5 logs
# because many of them are suboperations which are not gonna be kept
# Yet we still want to obtain ~limit number of logs
logs = logs[: limit * 5]
for log in logs: for log in logs:
base_filename = log[: -len(METADATA_FILE_EXT)] name = log[: -len(METADATA_FILE_EXT)]
md_path = os.path.join(OPERATIONS_PATH, log) md_path = os.path.join(OPERATIONS_PATH, log)
entry = { entry = {
"name": base_filename, "name": name,
"path": md_path, "path": md_path,
"description": _get_description_from_name(base_filename), "description": _get_description_from_name(name),
} }
try: try:
entry["started_at"] = _get_datetime_from_name(base_filename) entry["started_at"] = _get_datetime_from_name(name)
except ValueError: except ValueError:
pass pass
@ -138,10 +185,8 @@ def log_list(limit=None, with_details=False, with_suboperations=False):
if with_suboperations: if with_suboperations:
entry["parent"] = metadata.get("parent") entry["parent"] = metadata.get("parent")
entry["suboperations"] = [] entry["suboperations"] = []
elif metadata.get("parent") is not None:
continue
operations[base_filename] = entry operations[name] = entry
# When displaying suboperations, we build a tree-like structure where # When displaying suboperations, we build a tree-like structure where
# "suboperations" is a list of suboperations (each of them may also have a list of # "suboperations" is a list of suboperations (each of them may also have a list of
@ -788,7 +833,7 @@ class OperationLogger:
# Get the 20 lines before the last 'ynh_exit_properly' # Get the 20 lines before the last 'ynh_exit_properly'
rev_lines = list(reversed(lines)) rev_lines = list(reversed(lines))
for i, line in enumerate(rev_lines): for i, line in enumerate(rev_lines[:50]):
if line.endswith("+ ynh_exit_properly"): if line.endswith("+ ynh_exit_properly"):
lines_to_display = reversed(rev_lines[i : i + 20]) lines_to_display = reversed(rev_lines[i : i + 20])
break break

View file

@ -252,7 +252,11 @@ def aptitude_with_progress_bar(cmd):
if package == "dpkg-exec": if package == "dpkg-exec":
return return
if package and log_apt_status_to_progress_bar.previous_package and package == log_apt_status_to_progress_bar.previous_package: if (
package
and log_apt_status_to_progress_bar.previous_package
and package == log_apt_status_to_progress_bar.previous_package
):
return return
try: try:
@ -276,18 +280,22 @@ def aptitude_with_progress_bar(cmd):
log_apt_status_to_progress_bar.download_message_displayed = False log_apt_status_to_progress_bar.download_message_displayed = False
def strip_boring_dpkg_reading_database(s): def strip_boring_dpkg_reading_database(s):
return re.sub(r'(\(Reading database ... \d*%?|files and directories currently installed.\))', '', s) return re.sub(
r"(\(Reading database ... \d*%?|files and directories currently installed.\))",
"",
s,
)
callbacks = ( callbacks = (
lambda l: logger.debug(strip_boring_dpkg_reading_database(l).rstrip() + "\r"), lambda l: logger.debug(strip_boring_dpkg_reading_database(l).rstrip() + "\r"),
lambda l: logger.warning(l.rstrip() + "\r"), # ... aptitude has no stderr ? :| if _apt_log_line_is_relevant(l.rstrip()) else logger.debug(l.rstrip() + "\r"), lambda l: logger.warning(
l.rstrip() + "\r"
), # ... aptitude has no stderr ? :| if _apt_log_line_is_relevant(l.rstrip()) else logger.debug(l.rstrip() + "\r"),
lambda l: log_apt_status_to_progress_bar(l.rstrip()), lambda l: log_apt_status_to_progress_bar(l.rstrip()),
) )
original_cmd = cmd original_cmd = cmd
cmd = ( cmd = f'LC_ALL=C DEBIAN_FRONTEND=noninteractive APT_LISTCHANGES_FRONTEND=none aptitude {cmd} --quiet=2 -o=Dpkg::Use-Pty=0 -o "APT::Status-Fd=$YNH_STDINFO"'
f'LC_ALL=C DEBIAN_FRONTEND=noninteractive APT_LISTCHANGES_FRONTEND=none aptitude {cmd} --quiet=2 -o=Dpkg::Use-Pty=0 -o "APT::Status-Fd=$YNH_STDINFO"'
)
# If upgrading yunohost from the API, delay the Yunohost-api restart # If upgrading yunohost from the API, delay the Yunohost-api restart
# (this should be the last time we need it before bookworm, because on bookworm, yunohost-admin cookies will be persistent upon api restart) # (this should be the last time we need it before bookworm, because on bookworm, yunohost-admin cookies will be persistent upon api restart)
@ -299,12 +307,14 @@ def aptitude_with_progress_bar(cmd):
read, write = os.pipe() read, write = os.pipe()
os.write(write, b"y\ny\ny") os.write(write, b"y\ny\ny")
os.close(write) os.close(write)
ret = call_async_output(cmd, callbacks, shell=True) ret = call_async_output(cmd, callbacks, shell=True, stdin=read)
if log_apt_status_to_progress_bar.previous_package is not None and ret == 0: if log_apt_status_to_progress_bar.previous_package is not None and ret == 0:
log_apt_status_to_progress_bar("done::100:Done") log_apt_status_to_progress_bar("done::100:Done")
elif ret != 0: elif ret != 0:
raise YunohostError(f"Failed to run command 'aptitude {original_cmd}'", raw_msg=True) raise YunohostError(
f"Failed to run command 'aptitude {original_cmd}'", raw_msg=True
)
def _apt_log_line_is_relevant(line): def _apt_log_line_is_relevant(line):