mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge branch 'dev' into enh-csv
This commit is contained in:
commit
c20ca3015e
39 changed files with 423 additions and 162 deletions
173
bin/yunomdns
Executable file
173
bin/yunomdns
Executable file
|
@ -0,0 +1,173 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Pythonic declaration of mDNS .local domains for YunoHost
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import re
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
import socket
|
||||
from time import sleep
|
||||
from typing import List, Dict
|
||||
|
||||
from zeroconf import Zeroconf, ServiceInfo
|
||||
|
||||
# Helper command taken from Moulinette
|
||||
def check_output(args, stderr=subprocess.STDOUT, shell=True, **kwargs):
|
||||
"""Run command with arguments and return its output as a byte string
|
||||
Overwrite some of the arguments to capture standard error in the result
|
||||
and use shell by default before calling subprocess.check_output.
|
||||
"""
|
||||
return (
|
||||
subprocess.check_output(args, stderr=stderr, shell=shell, **kwargs)
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
)
|
||||
|
||||
# Helper command taken from Moulinette
|
||||
def _extract_inet(string, skip_netmask=False, skip_loopback=True):
|
||||
"""
|
||||
Extract IP addresses (v4 and/or v6) from a string limited to one
|
||||
address by protocol
|
||||
|
||||
Keyword argument:
|
||||
string -- String to search in
|
||||
skip_netmask -- True to skip subnet mask extraction
|
||||
skip_loopback -- False to include addresses reserved for the
|
||||
loopback interface
|
||||
|
||||
Returns:
|
||||
A dict of {protocol: address} with protocol one of 'ipv4' or 'ipv6'
|
||||
|
||||
"""
|
||||
ip4_pattern = (
|
||||
r"((25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}"
|
||||
)
|
||||
ip6_pattern = r"(((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::?((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)"
|
||||
ip4_pattern += r"/[0-9]{1,2})" if not skip_netmask else ")"
|
||||
ip6_pattern += r"/[0-9]{1,3})" if not skip_netmask else ")"
|
||||
result = {}
|
||||
|
||||
for m in re.finditer(ip4_pattern, string):
|
||||
addr = m.group(1)
|
||||
if skip_loopback and addr.startswith("127."):
|
||||
continue
|
||||
|
||||
# Limit to only one result
|
||||
result["ipv4"] = addr
|
||||
break
|
||||
|
||||
for m in re.finditer(ip6_pattern, string):
|
||||
addr = m.group(1)
|
||||
if skip_loopback and addr == "::1":
|
||||
continue
|
||||
|
||||
# Limit to only one result
|
||||
result["ipv6"] = addr
|
||||
break
|
||||
|
||||
return result
|
||||
|
||||
# Helper command taken from Moulinette
|
||||
def get_network_interfaces():
|
||||
|
||||
# Get network devices and their addresses (raw infos from 'ip addr')
|
||||
devices_raw = {}
|
||||
output = check_output("ip --brief a").split("\n")
|
||||
for line in output:
|
||||
line = line.split()
|
||||
iname = line[0]
|
||||
ips = ' '.join(line[2:])
|
||||
|
||||
devices_raw[iname] = ips
|
||||
|
||||
# Parse relevant informations for each of them
|
||||
devices = {
|
||||
name: _extract_inet(addrs)
|
||||
for name, addrs in devices_raw.items()
|
||||
if name != "lo"
|
||||
}
|
||||
|
||||
return devices
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
###
|
||||
# CONFIG
|
||||
###
|
||||
|
||||
with open('/etc/yunohost/mdns.yml', 'r') as f:
|
||||
config = yaml.safe_load(f) or {}
|
||||
updated = False
|
||||
|
||||
required_fields = ["interfaces", "domains"]
|
||||
missing_fields = [field for field in required_fields if field not in config]
|
||||
|
||||
if missing_fields:
|
||||
print("The fields %s are required" % ', '.join(missing_fields))
|
||||
|
||||
if config['interfaces'] is None:
|
||||
print('No interface listed for broadcast.')
|
||||
sys.exit(0)
|
||||
|
||||
if 'yunohost.local' not in config['domains']:
|
||||
config['domains'].append('yunohost.local')
|
||||
|
||||
zcs = {}
|
||||
interfaces = get_network_interfaces()
|
||||
for interface in config['interfaces']:
|
||||
infos = [] # List of ServiceInfo objects, to feed Zeroconf
|
||||
ips = [] # Human-readable IPs
|
||||
b_ips = [] # Binary-convered IPs
|
||||
|
||||
ipv4 = interfaces[interface]['ipv4'].split('/')[0]
|
||||
if ipv4:
|
||||
ips.append(ipv4)
|
||||
b_ips.append(socket.inet_pton(socket.AF_INET, ipv4))
|
||||
|
||||
ipv6 = interfaces[interface]['ipv6'].split('/')[0]
|
||||
if ipv6:
|
||||
ips.append(ipv6)
|
||||
b_ips.append(socket.inet_pton(socket.AF_INET6, ipv6))
|
||||
|
||||
# If at least one IP is listed
|
||||
if ips:
|
||||
# Create a Zeroconf object, and store the ServiceInfos
|
||||
zc = Zeroconf(interfaces=ips)
|
||||
zcs[zc]=[]
|
||||
for d in config['domains']:
|
||||
d_domain=d.replace('.local','')
|
||||
if '.' in d_domain:
|
||||
print(d_domain+'.local: subdomains are not supported.')
|
||||
else:
|
||||
# Create a ServiceInfo object for each .local domain
|
||||
zcs[zc].append(ServiceInfo(
|
||||
type_='_device-info._tcp.local.',
|
||||
name=interface+': '+d_domain+'._device-info._tcp.local.',
|
||||
addresses=b_ips,
|
||||
port=80,
|
||||
server=d+'.',
|
||||
))
|
||||
print('Adding '+d+' with addresses '+str(ips)+' on interface '+interface)
|
||||
|
||||
# Run registration
|
||||
print("Registering...")
|
||||
for zc, infos in zcs.items():
|
||||
for info in infos:
|
||||
zc.register_service(info)
|
||||
|
||||
try:
|
||||
print("Registered. Press Ctrl+C or stop service to stop.")
|
||||
while True:
|
||||
sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
print("Unregistering...")
|
||||
for zc, infos in zcs.items():
|
||||
for info in infos:
|
||||
zc.unregister_service(info)
|
||||
zc.close()
|
|
@ -695,7 +695,11 @@ app:
|
|||
api: DELETE /apps/<app>
|
||||
arguments:
|
||||
app:
|
||||
help: App to delete
|
||||
help: App to remove
|
||||
-p:
|
||||
full: --purge
|
||||
help: Also remove all application data
|
||||
action: store_true
|
||||
|
||||
### app_upgrade()
|
||||
upgrade:
|
||||
|
@ -715,6 +719,10 @@ app:
|
|||
full: --force
|
||||
help: Force the update, even though the app is up to date
|
||||
action: store_true
|
||||
-b:
|
||||
full: --no-safety-backup
|
||||
help: Disable the safety backup during upgrade
|
||||
action: store_true
|
||||
|
||||
### app_change_url()
|
||||
change-url:
|
||||
|
|
|
@ -32,7 +32,7 @@ def get_dict_actions(OPTION_SUBTREE, category):
|
|||
with open(ACTIONSMAP_FILE, "r") as stream:
|
||||
|
||||
# Getting the dictionary containning what actions are possible per category
|
||||
OPTION_TREE = yaml.load(stream)
|
||||
OPTION_TREE = yaml.safe_load(stream)
|
||||
|
||||
CATEGORY = [
|
||||
category for category in OPTION_TREE.keys() if not category.startswith("_")
|
||||
|
|
|
@ -31,7 +31,11 @@ ynh_multimedia_build_main_dir() {
|
|||
mkdir -p "$MEDIA_DIRECTORY/$user/eBook"
|
||||
ln -sfn "$MEDIA_DIRECTORY/share" "$MEDIA_DIRECTORY/$user/Share"
|
||||
# Création du lien symbolique dans le home de l'utilisateur.
|
||||
ln -sfn "$MEDIA_DIRECTORY/$user" "/home/$user/Multimedia"
|
||||
#link will only be created if the home directory of the user exists and if it's located in '/home' folder
|
||||
local user_home="$(getent passwd $user | cut -d: -f6 | grep '^/home/')"
|
||||
if [[ -d "$user_home" ]]; then
|
||||
ln -sfn "$MEDIA_DIRECTORY/$user" "$user_home/Multimedia"
|
||||
fi
|
||||
# Propriétaires des dossiers utilisateurs.
|
||||
chown -R $user "$MEDIA_DIRECTORY/$user"
|
||||
done
|
||||
|
|
|
@ -362,8 +362,17 @@ ynh_permission_has_user() {
|
|||
return 1
|
||||
fi
|
||||
|
||||
yunohost user permission info "$app.$permission" --output-as json --quiet \
|
||||
| jq -e --arg user $user '.corresponding_users | index($user)' >/dev/null
|
||||
# Check both allowed and corresponding_users sections in the json
|
||||
for section in "allowed" "corresponding_users"
|
||||
do
|
||||
if yunohost user permission info "$app.$permission" --output-as json --quiet \
|
||||
| jq -e --arg user $user --arg section $section '.[$section] | index($user)' >/dev/null
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if a legacy permissions exist
|
||||
|
|
|
@ -86,7 +86,7 @@ key, value = os.environ['KEY'], os.environ.get('VALUE', None)
|
|||
setting_file = "/etc/yunohost/apps/%s/settings.yml" % app
|
||||
assert os.path.exists(setting_file), "Setting file %s does not exists ?" % setting_file
|
||||
with open(setting_file) as f:
|
||||
settings = yaml.load(f)
|
||||
settings = yaml.safe_load(f)
|
||||
if action == "get":
|
||||
if key in settings:
|
||||
print(settings[key])
|
||||
|
@ -96,7 +96,7 @@ else:
|
|||
del settings[key]
|
||||
elif action == "set":
|
||||
if key in ['redirected_urls', 'redirected_regex']:
|
||||
value = yaml.load(value)
|
||||
value = yaml.safe_load(value)
|
||||
settings[key] = value
|
||||
else:
|
||||
raise ValueError("action should either be get, set or delete")
|
||||
|
|
|
@ -212,10 +212,10 @@ import yaml
|
|||
|
||||
|
||||
with open('services.yml') as f:
|
||||
new_services = yaml.load(f)
|
||||
new_services = yaml.safe_load(f)
|
||||
|
||||
with open('/etc/yunohost/services.yml') as f:
|
||||
services = yaml.load(f) or {}
|
||||
services = yaml.safe_load(f) or {}
|
||||
|
||||
updated = False
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
set -e
|
||||
|
||||
tmp_backup_dir_file="/tmp/slapd-backup-dir.txt"
|
||||
tmp_backup_dir_file="/root/slapd-backup-dir.txt"
|
||||
|
||||
config="/usr/share/yunohost/templates/slapd/config.ldif"
|
||||
db_init="/usr/share/yunohost/templates/slapd/db_init.ldif"
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/avahi-daemon
|
||||
|
||||
install -D -m 644 avahi-daemon.conf \
|
||||
"${pending_dir}/etc/avahi/avahi-daemon.conf"
|
||||
}
|
||||
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| systemctl restart avahi-daemon
|
||||
}
|
||||
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
case "$1" in
|
||||
pre)
|
||||
do_pre_regen $4
|
||||
;;
|
||||
post)
|
||||
do_post_regen $4
|
||||
;;
|
||||
*)
|
||||
echo "hook called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
83
data/hooks/conf_regen/37-mdns
Executable file
83
data/hooks/conf_regen/37-mdns
Executable file
|
@ -0,0 +1,83 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
_generate_config() {
|
||||
echo "domains:"
|
||||
echo " - yunohost.local"
|
||||
for domain in $YNH_DOMAINS
|
||||
do
|
||||
# Only keep .local domains (don't keep
|
||||
[[ "$domain" =~ [^.]+\.[^.]+\.local$ ]] && echo "Subdomain $domain cannot be handled by Bonjour/Zeroconf/mDNS" >&2
|
||||
[[ "$domain" =~ ^[^.]+\.local$ ]] || continue
|
||||
echo " - $domain"
|
||||
done
|
||||
|
||||
echo "interfaces:"
|
||||
local_network_interfaces="$(ip --brief a | grep ' 10\.\| 192\.168\.' | awk '{print $1}')"
|
||||
for interface in $local_network_interfaces
|
||||
do
|
||||
echo " - $interface"
|
||||
done
|
||||
}
|
||||
|
||||
do_init_regen() {
|
||||
do_pre_regen
|
||||
do_post_regen /etc/systemd/system/yunomdns.service
|
||||
systemctl enable yunomdns
|
||||
}
|
||||
|
||||
do_pre_regen() {
|
||||
pending_dir="$1"
|
||||
|
||||
cd /usr/share/yunohost/templates/mdns
|
||||
mkdir -p ${pending_dir}/etc/systemd/system/
|
||||
cp yunomdns.service ${pending_dir}/etc/systemd/system/
|
||||
|
||||
getent passwd mdns &>/dev/null || useradd --no-create-home --shell /usr/sbin/nologin --system --user-group mdns
|
||||
|
||||
mkdir -p ${pending_dir}/etc/yunohost
|
||||
_generate_config > ${pending_dir}/etc/yunohost/mdns.yml
|
||||
}
|
||||
|
||||
do_post_regen() {
|
||||
regen_conf_files="$1"
|
||||
|
||||
chown mdns:mdns /etc/yunohost/mdns.yml
|
||||
|
||||
# If we changed the systemd ynh-override conf
|
||||
if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/yunomdns.service$"
|
||||
then
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
# Legacy stuff to enable the new yunomdns service on legacy systems
|
||||
if [[ -e /etc/avahi/avahi-daemon.conf ]] && grep -q 'yunohost' /etc/avahi/avahi-daemon.conf
|
||||
then
|
||||
systemctl enable yunomdns
|
||||
fi
|
||||
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| systemctl restart yunomdns
|
||||
}
|
||||
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
case "$1" in
|
||||
pre)
|
||||
do_pre_regen $4
|
||||
;;
|
||||
post)
|
||||
do_post_regen $4
|
||||
;;
|
||||
init)
|
||||
do_init_regen
|
||||
;;
|
||||
*)
|
||||
echo "hook called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
|
@ -13,6 +13,7 @@ from yunohost.diagnosis import Diagnoser
|
|||
from yunohost.domain import domain_list, _build_dns_conf, _get_maindomain
|
||||
|
||||
YNH_DYNDNS_DOMAINS = ["nohost.me", "noho.st", "ynh.fr"]
|
||||
SPECIAL_USE_TLDS = ["local", "localhost", "onion", "test"]
|
||||
|
||||
|
||||
class DNSRecordsDiagnoser(Diagnoser):
|
||||
|
@ -29,8 +30,14 @@ class DNSRecordsDiagnoser(Diagnoser):
|
|||
for domain in all_domains:
|
||||
self.logger_debug("Diagnosing DNS conf for %s" % domain)
|
||||
is_subdomain = domain.split(".", 1)[1] in all_domains
|
||||
is_specialusedomain = any(
|
||||
domain.endswith("." + tld) for tld in SPECIAL_USE_TLDS
|
||||
)
|
||||
for report in self.check_domain(
|
||||
domain, domain == main_domain, is_subdomain=is_subdomain
|
||||
domain,
|
||||
domain == main_domain,
|
||||
is_subdomain=is_subdomain,
|
||||
is_specialusedomain=is_specialusedomain,
|
||||
):
|
||||
yield report
|
||||
|
||||
|
@ -48,7 +55,7 @@ class DNSRecordsDiagnoser(Diagnoser):
|
|||
for report in self.check_expiration_date(domains_from_registrar):
|
||||
yield report
|
||||
|
||||
def check_domain(self, domain, is_main_domain, is_subdomain):
|
||||
def check_domain(self, domain, is_main_domain, is_subdomain, is_specialusedomain):
|
||||
|
||||
expected_configuration = _build_dns_conf(
|
||||
domain, include_empty_AAAA_if_no_ipv6=True
|
||||
|
@ -59,6 +66,15 @@ class DNSRecordsDiagnoser(Diagnoser):
|
|||
if is_subdomain:
|
||||
categories = ["basic"]
|
||||
|
||||
if is_specialusedomain:
|
||||
categories = []
|
||||
yield dict(
|
||||
meta={"domain": domain},
|
||||
data={},
|
||||
status="INFO",
|
||||
summary="diagnosis_dns_specialusedomain",
|
||||
)
|
||||
|
||||
for category in categories:
|
||||
|
||||
records = expected_configuration[category]
|
||||
|
|
|
@ -34,6 +34,12 @@ class WebDiagnoser(Diagnoser):
|
|||
summary="diagnosis_http_nginx_conf_not_up_to_date",
|
||||
details=["diagnosis_http_nginx_conf_not_up_to_date_details"],
|
||||
)
|
||||
elif domain.endswith(".local"):
|
||||
yield dict(
|
||||
meta={"domain": domain},
|
||||
status="INFO",
|
||||
summary="diagnosis_http_localdomain",
|
||||
)
|
||||
else:
|
||||
domains_to_check.append(domain)
|
||||
|
||||
|
|
|
@ -15,7 +15,11 @@ mkdir -p "$MEDIA_DIRECTORY/$user/Video"
|
|||
mkdir -p "$MEDIA_DIRECTORY/$user/eBook"
|
||||
ln -sfn "$MEDIA_DIRECTORY/share" "$MEDIA_DIRECTORY/$user/Share"
|
||||
# Création du lien symbolique dans le home de l'utilisateur.
|
||||
ln -sfn "$MEDIA_DIRECTORY/$user" "/home/$user/Multimedia"
|
||||
#link will only be created if the home directory of the user exists and if it's located in '/home' folder
|
||||
local user_home="$(getent passwd $user | cut -d: -f6 | grep '^/home/')"
|
||||
if [[ -d "$user_home" ]]; then
|
||||
ln -sfn "$MEDIA_DIRECTORY/$user" "$user_home/Multimedia"
|
||||
fi
|
||||
# Propriétaires des dossiers utilisateurs.
|
||||
chown -R $user "$MEDIA_DIRECTORY/$user"
|
||||
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
# This file is part of avahi.
|
||||
#
|
||||
# avahi is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# avahi is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with avahi; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
# USA.
|
||||
|
||||
# See avahi-daemon.conf(5) for more information on this configuration
|
||||
# file!
|
||||
|
||||
[server]
|
||||
host-name=yunohost
|
||||
domain-name=local
|
||||
#browse-domains=0pointer.de, zeroconf.org
|
||||
use-ipv4=yes
|
||||
use-ipv6=yes
|
||||
#allow-interfaces=eth0
|
||||
#deny-interfaces=eth1
|
||||
#check-response-ttl=no
|
||||
#use-iff-running=no
|
||||
#enable-dbus=yes
|
||||
#disallow-other-stacks=no
|
||||
#allow-point-to-point=no
|
||||
#cache-entries-max=4096
|
||||
#clients-max=4096
|
||||
#objects-per-client-max=1024
|
||||
#entries-per-entry-group-max=32
|
||||
ratelimit-interval-usec=1000000
|
||||
ratelimit-burst=1000
|
||||
|
||||
[wide-area]
|
||||
enable-wide-area=yes
|
||||
|
||||
[publish]
|
||||
#disable-publishing=no
|
||||
#disable-user-service-publishing=no
|
||||
#add-service-cookie=no
|
||||
#publish-addresses=yes
|
||||
#publish-hinfo=yes
|
||||
#publish-workstation=yes
|
||||
#publish-domain=yes
|
||||
#publish-dns-servers=192.168.50.1, 192.168.50.2
|
||||
#publish-resolv-conf-dns-servers=yes
|
||||
#publish-aaaa-on-ipv4=yes
|
||||
#publish-a-on-ipv6=no
|
||||
|
||||
[reflector]
|
||||
#enable-reflector=no
|
||||
#reflect-ipv=no
|
||||
|
||||
[rlimits]
|
||||
#rlimit-as=
|
||||
rlimit-core=0
|
||||
rlimit-data=4194304
|
||||
rlimit-fsize=0
|
||||
rlimit-nofile=768
|
||||
rlimit-stack=4194304
|
||||
rlimit-nproc=3
|
13
data/templates/mdns/yunomdns.service
Normal file
13
data/templates/mdns/yunomdns.service
Normal file
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=YunoHost mDNS service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=mdns
|
||||
Group=mdns
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/yunomdns
|
||||
StandardOutput=syslog
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
|
@ -1,4 +1,3 @@
|
|||
avahi-daemon: {}
|
||||
dnsmasq:
|
||||
test_conf: dnsmasq --test
|
||||
dovecot:
|
||||
|
@ -52,6 +51,8 @@ yunohost-firewall:
|
|||
need_lock: true
|
||||
test_status: iptables -S | grep "^-A INPUT" | grep " --dport" | grep -q ACCEPT
|
||||
category: security
|
||||
yunomdns:
|
||||
category: mdns
|
||||
glances: null
|
||||
nsswitch: null
|
||||
ssl: null
|
||||
|
@ -68,3 +69,4 @@ rmilter: null
|
|||
php5-fpm: null
|
||||
php7.0-fpm: null
|
||||
nslcd: null
|
||||
avahi-daemon: null
|
||||
|
|
21
debian/changelog
vendored
21
debian/changelog
vendored
|
@ -1,3 +1,24 @@
|
|||
yunohost (4.2.8.1) stable; urgency=low
|
||||
|
||||
- [fix] Safer location for slapd backup during hdb/mdb migration (3c646b3d)
|
||||
|
||||
Thanks to all contributors <3 ! (ljf)
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 27 Aug 2021 01:32:16 +0200
|
||||
|
||||
yunohost (4.2.8) stable; urgency=low
|
||||
|
||||
- [fix] ynh_permission_has_user not behaving properly when checking if a group is allowed (f0590907)
|
||||
- [enh] use yaml safeloader everywhere ([#1287](https://github.com/YunoHost/yunohost/pull/1287))
|
||||
- [enh] Add --no-safety-backup option to "yunohost app upgrade" ([#1286](https://github.com/YunoHost/yunohost/pull/1286))
|
||||
- [enh] Add --purge option to "yunohost app remove" ([#1285](https://github.com/YunoHost/yunohost/pull/1285))
|
||||
- [enh] Multimedia helper: check that home folder exists ([#1255](https://github.com/YunoHost/yunohost/pull/1255))
|
||||
- [i18n] Translations updated for French, Galician, German, Portuguese
|
||||
|
||||
Thanks to all contributors <3 ! (José M, Kay0u, Krakinou, ljf, Luca, mifegui, ppr, sagessylu)
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 19 Aug 2021 19:11:19 +0200
|
||||
|
||||
yunohost (4.2.7) stable; urgency=low
|
||||
|
||||
Notable changes:
|
||||
|
|
5
debian/control
vendored
5
debian/control
vendored
|
@ -13,14 +13,15 @@ Depends: ${python3:Depends}, ${misc:Depends}
|
|||
, moulinette (>= 4.2), ssowat (>= 4.0)
|
||||
, python3-psutil, python3-requests, python3-dnspython, python3-openssl
|
||||
, python3-miniupnpc, python3-dbus, python3-jinja2
|
||||
, python3-toml, python3-packaging, python3-publicsuffix
|
||||
, python3-toml, python3-packaging, python3-publicsuffix,
|
||||
, python3-zeroconf,
|
||||
, apt, apt-transport-https, apt-utils, dirmngr
|
||||
, php7.3-common, php7.3-fpm, php7.3-ldap, php7.3-intl
|
||||
, mariadb-server, php7.3-mysql
|
||||
, openssh-server, iptables, fail2ban, dnsutils, bind9utils
|
||||
, openssl, ca-certificates, netcat-openbsd, iproute2
|
||||
, slapd, ldap-utils, sudo-ldap, libnss-ldapd, unscd, libpam-ldapd
|
||||
, dnsmasq, avahi-daemon, libnss-mdns, resolvconf, libnss-myhostname
|
||||
, dnsmasq, resolvconf, libnss-myhostname
|
||||
, postfix, postfix-ldap, postfix-policyd-spf-perl, postfix-pcre
|
||||
, dovecot-core, dovecot-ldap, dovecot-lmtpd, dovecot-managesieved, dovecot-antispam
|
||||
, rspamd, opendkim-tools, postsrsd, procmail, mailutils
|
||||
|
|
1
debian/postinst
vendored
1
debian/postinst
vendored
|
@ -18,6 +18,7 @@ do_configure() {
|
|||
bash /usr/share/yunohost/hooks/conf_regen/46-nsswitch init
|
||||
bash /usr/share/yunohost/hooks/conf_regen/06-slapd init
|
||||
bash /usr/share/yunohost/hooks/conf_regen/15-nginx init
|
||||
bash /usr/share/yunohost/hooks/conf_regen/37-mdns init
|
||||
fi
|
||||
else
|
||||
echo "Regenerating configuration, this might take a while..."
|
||||
|
|
|
@ -26,7 +26,7 @@ ACTIONSMAP_FILE = os.path.join(THIS_SCRIPT_DIR, "../data/actionsmap/yunohost.yml
|
|||
|
||||
|
||||
def ordered_yaml_load(stream):
|
||||
class OrderedLoader(yaml.Loader):
|
||||
class OrderedLoader(yaml.SafeLoader):
|
||||
pass
|
||||
|
||||
OrderedLoader.add_constructor(
|
||||
|
|
|
@ -83,7 +83,6 @@
|
|||
"yunohost_installing": "عملية تنصيب يونوهوست جارية …",
|
||||
"yunohost_not_installed": "إنَّ واي يونوهوست ليس مُنَصَّب أو هو مثبت حاليا بشكل خاطئ. قم بتنفيذ الأمر 'yunohost tools postinstall'",
|
||||
"migrations_list_conflict_pending_done": "لا يمكنك استخدام --previous و --done معًا على نفس سطر الأوامر.",
|
||||
"service_description_avahi-daemon": "يسمح لك بالنفاذ إلى خادومك عبر الشبكة المحلية باستخدام yunohost.local",
|
||||
"service_description_metronome": "يُدير حسابات الدردشة الفورية XMPP",
|
||||
"service_description_nginx": "يقوم بتوفير النفاذ و السماح بالوصول إلى كافة مواقع الويب المستضافة على خادومك",
|
||||
"service_description_postfix": "يقوم بإرسال و تلقي الرسائل البريدية الإلكترونية",
|
||||
|
|
|
@ -283,7 +283,6 @@
|
|||
"service_already_started": "El servei «{service}» ja està funcionant",
|
||||
"service_already_stopped": "Ja s'ha aturat el servei «{service}»",
|
||||
"service_cmd_exec_failed": "No s'ha pogut executar l'ordre «{command}»",
|
||||
"service_description_avahi-daemon": "Permet accedir al servidor via «yunohost.local» en la xarxa local",
|
||||
"service_description_dnsmasq": "Gestiona la resolució del nom de domini (DNS)",
|
||||
"service_description_dovecot": "Permet als clients de correu accedir/recuperar correus (via IMAP i POP3)",
|
||||
"service_description_fail2ban": "Protegeix contra els atacs de força bruta i a altres atacs provinents d'Internet",
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
"upnp_dev_not_found": "Es konnten keine UPnP Geräte gefunden werden",
|
||||
"upnp_disabled": "UPnP deaktiviert",
|
||||
"upnp_enabled": "UPnP aktiviert",
|
||||
"upnp_port_open_failed": "UPnP Port konnte nicht geöffnet werden.",
|
||||
"upnp_port_open_failed": "Port konnte nicht via UPnP geöffnet werden",
|
||||
"user_created": "Benutzer erstellt",
|
||||
"user_creation_failed": "Benutzer konnte nicht erstellt werden {user}: {error}",
|
||||
"user_deleted": "Benutzer gelöscht",
|
||||
|
@ -528,7 +528,7 @@
|
|||
"migrations_no_such_migration": "Es existiert keine Migration genannt '{id}'",
|
||||
"migrations_running_forward": "Durchführen der Migrationen {id}...",
|
||||
"migrations_skip_migration": "Überspringe Migrationen {id}...",
|
||||
"password_too_simple_2": "Dieses Passwort gehört zu den meistverwendeten der Welt. Bitte nehmen Sie etwas einzigartigeres",
|
||||
"password_too_simple_2": "Das Passwort muss mindestens 8 Zeichen lang sein und Gross- sowie Kleinbuchstaben enthalten",
|
||||
"password_listed": "Dieses Passwort zählt zu den meistgenutzten Passwörtern der Welt. Bitte wähle ein anderes, einzigartigeres Passwort.",
|
||||
"operation_interrupted": "Wurde die Operation manuell unterbrochen?",
|
||||
"invalid_number": "Muss eine Zahl sein",
|
||||
|
@ -539,8 +539,8 @@
|
|||
"permission_already_allowed": "Die Gruppe '{group}' hat die Berechtigung '{permission}' bereits erhalten",
|
||||
"pattern_password_app": "Entschuldigen Sie bitte! Passwörter dürfen folgende Zeichen nicht enthalten: {forbidden_chars}",
|
||||
"pattern_email_forward": "Es muss sich um eine gültige E-Mail-Adresse handeln. Das Symbol '+' wird akzeptiert (zum Beispiel : maxmuster@beispiel.com oder maxmuster+yunohost@beispiel.com)",
|
||||
"password_too_simple_4": "Dass Passwort muss mindestens 12 Zeichen lang sein und Zahlen, Klein- und Grossbuchstaben und Sonderzeichen enthalten",
|
||||
"password_too_simple_3": "Das Passwort muss mindestens 8 Zeichen lang sein und Zahlen, Klein- und Grossbuchstaben und Sonderzeichen enthalten",
|
||||
"password_too_simple_4": "Das Passwort muss mindestens 12 Zeichen lang sein und Grossbuchstaben, Kleinbuchstaben, Zahlen und Sonderzeichen enthalten",
|
||||
"password_too_simple_3": "Das Passwort muss mindestens 8 Zeichen lang sein und Grossbuchstaben, Kleinbuchstaben, Zahlen und Sonderzeichen enthalten",
|
||||
"regenconf_file_manually_removed": "Die Konfigurationsdatei '{conf}' wurde manuell gelöscht und wird nicht erstellt",
|
||||
"regenconf_file_manually_modified": "Die Konfigurationsdatei '{conf}' wurde manuell bearbeitet und wird nicht aktualisiert",
|
||||
"regenconf_file_kept_back": "Die Konfigurationsdatei '{conf}' sollte von \"regen-conf\" (Kategorie {category}) gelöscht werden, wurde aber beibehalten.",
|
||||
|
@ -597,7 +597,6 @@
|
|||
"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_dnsmasq": "Verarbeitet die Auflösung des Domainnamens (DNS)",
|
||||
"service_description_avahi-daemon": "Erlaubt, den Server im lokalen Netz über 'yunohost.local' zu erreichen",
|
||||
"restore_backup_too_old": "Dieses Backup kann nicht wieder hergestellt werden, weil es von einer zu alten YunoHost Version stammt.",
|
||||
"service_description_slapd": "Speichert Benutzer, Domains und verbundene Informationen",
|
||||
"service_description_rspamd": "Spamfilter und andere E-Mail-Merkmale",
|
||||
|
@ -631,5 +630,9 @@
|
|||
"unknown_main_domain_path": "Unbekannte:r Domain oder Pfad für '{app}'. Du musst eine Domain und einen Pfad setzen, um die URL für Berechtigungen zu setzen.",
|
||||
"yunohost_postinstall_end_tip": "Post-install ist fertig! Um das Setup abzuschliessen, wird empfohlen:\n - einen ersten Benutzer über den Bereich 'Benutzer*in' 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.",
|
||||
"user_already_exists": "Der Benutzer '{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}",
|
||||
"global_settings_setting_security_webadmin_allowlist": "IP-Adressen, die auf die Verwaltungsseite zugreifen dürfen. Kommasepariert.",
|
||||
"global_settings_setting_security_webadmin_allowlist_enabled": "Erlaube nur bestimmten IP-Adressen den Zugriff auf die Verwaltungsseite.",
|
||||
"disk_space_not_sufficient_update": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu aktuallisieren",
|
||||
"disk_space_not_sufficient_install": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu installieren"
|
||||
}
|
|
@ -32,7 +32,7 @@
|
|||
"app_location_unavailable": "This URL is either unavailable, or conflicts with the already installed app(s):\n{apps}",
|
||||
"app_manifest_invalid": "Something is wrong with the app manifest: {error}",
|
||||
"app_manifest_install_ask_domain": "Choose the domain where this app should be installed",
|
||||
"app_manifest_install_ask_path": "Choose the path where this app should be installed",
|
||||
"app_manifest_install_ask_path": "Choose the URL path (after the domain) where this app should be installed",
|
||||
"app_manifest_install_ask_password": "Choose an administration password for this app",
|
||||
"app_manifest_install_ask_admin": "Choose an administrator user for this app",
|
||||
"app_manifest_install_ask_is_public": "Should this app be exposed to anonymous visitors?",
|
||||
|
@ -183,6 +183,7 @@
|
|||
"diagnosis_dns_discrepancy": "The following DNS record does not seem to follow the recommended configuration:<br>Type: <code>{type}</code><br>Name: <code>{name}</code><br>Current value: <code>{current}</code><br>Expected value: <code>{value}</code>",
|
||||
"diagnosis_dns_point_to_doc": "Please check the documentation at <a href='https://yunohost.org/dns_config'>https://yunohost.org/dns_config</a> if you need help about configuring DNS records.",
|
||||
"diagnosis_dns_try_dyndns_update_force": "This domain's DNS configuration should automatically be managed by YunoHost. If that's not the case, you can try to force an update using <cmd>yunohost dyndns update --force</cmd>.",
|
||||
"diagnosis_dns_specialusedomain": "Domain {domain} is based on a special-use top-level domain (TLD) and is therefore not expected to have actual DNS records.",
|
||||
"diagnosis_domain_expiration_not_found": "Unable to check the expiration date for some domains",
|
||||
"diagnosis_domain_not_found_details": "The domain {domain} doesn't exist in WHOIS database or is expired!",
|
||||
"diagnosis_domain_expiration_not_found_details": "The WHOIS information for domain {domain} doesn't seem to contain the information about the expiration date?",
|
||||
|
@ -259,6 +260,7 @@
|
|||
"diagnosis_http_hairpinning_issue_details": "This is probably because of your ISP box / router. As a result, people from outside your local network will be able to access your server as expected, but not people from inside the local network (like you, probably?) when using the domain name or global IP. You may be able to improve the situation by having a look at <a href='https://yunohost.org/dns_local_network'>https://yunohost.org/dns_local_network</a>",
|
||||
"diagnosis_http_could_not_diagnose": "Could not diagnose if domains are reachable from outside in IPv{ipversion}.",
|
||||
"diagnosis_http_could_not_diagnose_details": "Error: {error}",
|
||||
"diagnosis_http_localdomain": "Domain {domain}, with a .local TLD, is not expected to be reached from outside the local network.",
|
||||
"diagnosis_http_ok": "Domain {domain} is reachable through HTTP from outside the local network.",
|
||||
"diagnosis_http_timeout": "Timed-out while trying to contact your server from 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_connection_error": "Connection error: could not connect to the requested domain, it's very likely unreachable.",
|
||||
|
@ -397,7 +399,7 @@
|
|||
"log_letsencrypt_cert_install": "Install a Let's Encrypt certificate on '{}' domain",
|
||||
"log_permission_create": "Create permission '{}'",
|
||||
"log_permission_delete": "Delete permission '{}'",
|
||||
"log_permission_url": "Update url related to permission '{}'",
|
||||
"log_permission_url": "Update URL related to permission '{}'",
|
||||
"log_selfsigned_cert_install": "Install self-signed certificate on '{}' domain",
|
||||
"log_letsencrypt_cert_renew": "Renew '{}' Let's Encrypt certificate",
|
||||
"log_regen_conf": "Regenerate system configurations '{}'",
|
||||
|
@ -560,7 +562,7 @@
|
|||
"service_already_started": "The service '{service}' is running already",
|
||||
"service_already_stopped": "The service '{service}' has already been stopped",
|
||||
"service_cmd_exec_failed": "Could not execute the command '{command}'",
|
||||
"service_description_avahi-daemon": "Allows you to reach your server using 'yunohost.local' in your local network",
|
||||
"service_description_yunomdns": "Allows you to reach your server using 'yunohost.local' in your local network",
|
||||
"service_description_dnsmasq": "Handles domain name resolution (DNS)",
|
||||
"service_description_dovecot": "Allows e-mail clients to access/fetch email (via IMAP and POP3)",
|
||||
"service_description_fail2ban": "Protects against brute-force and other kinds of attacks from the Internet",
|
||||
|
|
|
@ -332,7 +332,6 @@
|
|||
"hook_exec_failed": "Ne povis funkcii skripto: {path}",
|
||||
"global_settings_cant_open_settings": "Ne eblis malfermi agordojn, tial: {reason}",
|
||||
"user_created": "Uzanto kreita",
|
||||
"service_description_avahi-daemon": "Permesas al vi atingi vian servilon uzante 'yunohost.local' en via loka reto",
|
||||
"certmanager_attempt_to_replace_valid_cert": "Vi provas anstataŭigi bonan kaj validan atestilon por domajno {domain}! (Uzu --forte pretervidi)",
|
||||
"regenconf_updated": "Agordo ĝisdatigita por '{category}'",
|
||||
"update_apt_cache_warning": "Io iris malbone dum la ĝisdatigo de la kaŝmemoro de APT (paka administranto de Debian). Jen rubujo de la sources.list-linioj, kiuj povus helpi identigi problemajn liniojn:\n{sourceslist}",
|
||||
|
|
|
@ -238,7 +238,6 @@
|
|||
"service_description_fail2ban": "Protege contra ataques de fuerza bruta y otras clases de ataques desde Internet",
|
||||
"service_description_dovecot": "Permite a los clientes de correo acceder/obtener correo (vía IMAP y POP3)",
|
||||
"service_description_dnsmasq": "Maneja la resolución de nombres de dominio (DNS)",
|
||||
"service_description_avahi-daemon": "Permite acceder a su servidor usando «yunohost.local» en su red local",
|
||||
"server_reboot_confirm": "El servidor se reiniciará inmediatamente ¿está seguro? [{answers}]",
|
||||
"server_reboot": "El servidor se reiniciará",
|
||||
"server_shutdown_confirm": "El servidor se apagará inmediatamente ¿está seguro? [{answers}]",
|
||||
|
|
|
@ -234,7 +234,7 @@
|
|||
"migrations_list_conflict_pending_done": "Vous ne pouvez pas utiliser --previous et --done simultanément.",
|
||||
"migrations_to_be_ran_manually": "La migration {id} doit être lancée manuellement. Veuillez aller dans Outils > Migrations dans l’interface admin, ou lancer `yunohost tools migrations run`.",
|
||||
"migrations_need_to_accept_disclaimer": "Pour lancer la migration {id}, vous devez accepter cet avertissement :\n---\n{disclaimer}\n---\nSi vous acceptez de lancer la migration, veuillez relancer la commande avec l’option --accept-disclaimer.",
|
||||
"service_description_avahi-daemon": "Vous permet d’atteindre votre serveur en utilisant « yunohost.local » sur votre réseau local",
|
||||
"service_description_yunomdns": "Vous permet d’atteindre votre serveur en utilisant « yunohost.local » sur votre réseau local",
|
||||
"service_description_dnsmasq": "Gère la résolution des noms de domaine (DNS)",
|
||||
"service_description_dovecot": "Permet aux clients de messagerie d’accéder/récupérer les courriels (via IMAP et POP3)",
|
||||
"service_description_fail2ban": "Protège contre les attaques brute-force et autres types d’attaques venant d’Internet",
|
||||
|
@ -633,5 +633,7 @@
|
|||
"diagnosis_sshd_config_inconsistent_details": "Veuillez exécuter <cmd>yunohost settings set security.ssh.port -v VOTRE_PORT_SSH</cmd> pour définir le port SSH, et vérifiez <cmd>yunohost tools regen-conf ssh --dry-run --with-diff</cmd> et <cmd>yunohost tools regen-conf ssh --force</cmd> pour réinitialiser votre configuration aux recommandations YunoHost.",
|
||||
"diagnosis_sshd_config_inconsistent": "Il semble que le port SSH a été modifié manuellement dans /etc/ssh/sshd_config. Depuis YunoHost 4.2, un nouveau paramètre global 'security.ssh.port' est disponible pour éviter de modifier manuellement la configuration.",
|
||||
"diagnosis_sshd_config_insecure": "La configuration SSH semble avoir été modifiée manuellement et n'est pas sécurisée car elle ne contient aucune directive 'AllowGroups' ou 'AllowUsers' pour limiter l'accès aux utilisateurs autorisés.",
|
||||
"backup_create_size_estimation": "L'archive contiendra environ {size} de données."
|
||||
"backup_create_size_estimation": "L'archive contiendra environ {size} de données.",
|
||||
"global_settings_setting_security_webadmin_allowlist": "Adresses IP autorisées à accéder à la page web du portail d'administration (webadmin). Elles doivent être séparées par une virgule.",
|
||||
"global_settings_setting_security_webadmin_allowlist_enabled": "Autorisez seulement certaines IP à accéder à la page web du portail d'administration (webadmin)."
|
||||
}
|
|
@ -67,7 +67,7 @@
|
|||
"app_remove_after_failed_install": "Eliminando a app debido ao fallo na instalación...",
|
||||
"app_requirements_unmeet": "Non se cumpren os requerimentos de {app}, o paquete {pkgname} ({version}) debe ser {spec}",
|
||||
"app_requirements_checking": "Comprobando os paquetes requeridos por {app}...",
|
||||
"app_removed": "{app} eliminada",
|
||||
"app_removed": "{app} desinstalada",
|
||||
"app_not_properly_removed": "{app} non se eliminou de xeito correcto",
|
||||
"app_not_installed": "Non se puido atopar {app} na lista de apps instaladas: {all_apps}",
|
||||
"app_not_correctly_installed": "{app} semella que non está instalada correctamente",
|
||||
|
@ -345,5 +345,17 @@
|
|||
"global_settings_setting_smtp_relay_password": "Contrasinal no repetidor SMTP",
|
||||
"global_settings_setting_smtp_relay_user": "Conta de usuaria no repetidor SMTP",
|
||||
"global_settings_setting_smtp_relay_port": "Porto do repetidor SMTP",
|
||||
"global_settings_setting_smtp_relay_host": "Servidor repetidor SMTP para enviar emails no lugar da túa instancia yunohost. É útil se estás nunha destas situacións: o teu porto 25 está bloqueado polo teu provedor ISP u VPN, se tes unha IP residencial nunha lista DUHL, se non podes configurar DNS inversa ou se este servidor non ten conexión directa a internet e queres utilizar outro para enviar os emails."
|
||||
"global_settings_setting_smtp_relay_host": "Servidor repetidor SMTP para enviar emails no lugar da túa instancia yunohost. É útil se estás nunha destas situacións: o teu porto 25 está bloqueado polo teu provedor ISP u VPN, se tes unha IP residencial nunha lista DUHL, se non podes configurar DNS inversa ou se este servidor non ten conexión directa a internet e queres utilizar outro para enviar os emails.",
|
||||
"group_updated": "Grupo '{group}' actualizado",
|
||||
"group_unknown": "Grupo descoñecido '{group}'",
|
||||
"group_deletion_failed": "Non se eliminou o grupo '{group}': {error}",
|
||||
"group_deleted": "Grupo '{group}' eliminado",
|
||||
"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_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",
|
||||
"global_settings_setting_security_webadmin_allowlist": "Enderezos IP con permiso para acceder á webadmin. Separados por vírgulas.",
|
||||
"global_settings_setting_security_webadmin_allowlist_enabled": "Permitir que só algúns IPs accedan á webadmin.",
|
||||
"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"
|
||||
}
|
|
@ -428,7 +428,6 @@
|
|||
"service_description_fail2ban": "Ti protegge dal brute-force e altri tipi di attacchi da Internet",
|
||||
"service_description_dovecot": "Consente ai client mail di accedere/recuperare le email (via IMAP e POP3)",
|
||||
"service_description_dnsmasq": "Gestisce la risoluzione dei domini (DNS)",
|
||||
"service_description_avahi-daemon": "Consente di raggiungere il tuo server eseguendo 'yunohost.local' sulla tua LAN",
|
||||
"server_reboot_confirm": "Il server si riavvierà immediatamente, sei sicuro? [{answers}]",
|
||||
"server_reboot": "Il server si riavvierà",
|
||||
"server_shutdown_confirm": "Il server si spegnerà immediatamente, sei sicuro? [{answers}]",
|
||||
|
|
|
@ -193,7 +193,6 @@
|
|||
"user_unknown": "Utilizaire « {user} » desconegut",
|
||||
"user_update_failed": "Modificacion impossibla de l’utilizaire",
|
||||
"user_updated": "L’utilizaire es estat modificat",
|
||||
"service_description_avahi-daemon": "permet d’aténher vòstre servidor via yunohost.local sus vòstre ret local",
|
||||
"service_description_dnsmasq": "gerís la resolucion dels noms de domeni (DNS)",
|
||||
"updating_apt_cache": "Actualizacion de la lista dels paquets disponibles…",
|
||||
"server_reboot_confirm": "Lo servidor es per reaviar sul pic, o volètz vertadièrament ? {answers}",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"action_invalid": "Acção Inválida '{action}'",
|
||||
"admin_password": "Senha de administração",
|
||||
"admin_password_change_failed": "Não é possível alterar a senha",
|
||||
"admin_password_change_failed": "Não foi possível alterar a senha",
|
||||
"admin_password_changed": "A senha da administração foi alterada",
|
||||
"app_already_installed": "{app} já está instalada",
|
||||
"app_extraction_failed": "Não foi possível extrair os ficheiros para instalação",
|
||||
|
@ -108,12 +108,12 @@
|
|||
"backup_hook_unknown": "Gancho de backup '{hook}' desconhecido",
|
||||
"backup_nothings_done": "Não há nada para guardar",
|
||||
"backup_output_directory_forbidden": "Diretório de saída proibido. Os backups não podem ser criados em /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ou /home/yunohost.backup/archives subpastas",
|
||||
"app_already_installed_cant_change_url": "Este aplicativo já está instalado. A URL não pode ser alterada apenas por esta função. Olhe para o `app changeurl` se estiver disponível.",
|
||||
"app_already_installed_cant_change_url": "Este aplicativo já está instalado. A URL não pode ser alterada apenas por esta função. Confira em `app changeurl` se está disponível.",
|
||||
"app_already_up_to_date": "{app} já está atualizado",
|
||||
"app_argument_choice_invalid": "Escolha inválida para o argumento '{name}', deve ser um dos {choices}",
|
||||
"app_argument_invalid": "Valor inválido de argumento '{name}': {error}",
|
||||
"app_argument_choice_invalid": "Use uma das opções '{choices}' para o argumento '{name}'",
|
||||
"app_argument_invalid": "Escolha um valor válido para o argumento '{name}': {error}",
|
||||
"app_argument_required": "O argumento '{name}' é obrigatório",
|
||||
"app_change_url_failed_nginx_reload": "Falha ao reiniciar o nginx. Aqui está o retorno de 'nginx -t':\n{nginx_errors}",
|
||||
"app_change_url_failed_nginx_reload": "Não foi possível reiniciar o nginx. Aqui está o retorno de 'nginx -t':\n{nginx_errors}",
|
||||
"app_location_unavailable": "Esta url não está disponível ou está em conflito com outra aplicação já instalada",
|
||||
"app_upgrade_app_name": "Atualizando aplicação {app}…",
|
||||
"app_upgrade_some_app_failed": "Não foi possível atualizar algumas aplicações",
|
||||
|
@ -129,5 +129,12 @@
|
|||
"app_change_url_identical_domains": "O antigo e o novo domínio / url_path são idênticos ('{domain}{path}'), nada para fazer.",
|
||||
"password_too_simple_1": "A senha precisa ter pelo menos 8 caracteres",
|
||||
"admin_password_too_long": "Escolha uma senha que contenha menos de 127 caracteres",
|
||||
"aborting": "Abortando."
|
||||
"aborting": "Abortando.",
|
||||
"app_change_url_no_script": "A aplicação '{app_name}' ainda não permite modificar a URL. Talvez devesse atualizá-la.",
|
||||
"app_argument_password_no_default": "Erro ao interpretar argumento da senha '{name}': O argumento da senha não pode ter um valor padrão por segurança",
|
||||
"app_action_cannot_be_ran_because_required_services_down": "Estes serviços devem estar funcionado para executar esta ação: {services}. Tente reiniciá-los para continuar (e possivelmente investigar o porquê de não estarem funcionado).",
|
||||
"app_action_broke_system": "Esta ação parece ter quebrado estes serviços importantes: {services}",
|
||||
"already_up_to_date": "Nada a ser feito. Tudo já está atualizado.",
|
||||
"additional_urls_already_removed": "A URL adicional '{url}'já está removida para a permissão '{permission}'",
|
||||
"additional_urls_already_added": "A URL adicional '{url}' já está adicionada para a permissão '{permission}'"
|
||||
}
|
|
@ -226,7 +226,6 @@
|
|||
"service_description_fail2ban": "防止来自互联网的暴力攻击和其他类型的攻击",
|
||||
"service_description_dovecot": "允许电子邮件客户端访问/获取电子邮件(通过IMAP和POP3)",
|
||||
"service_description_dnsmasq": "处理域名解析(DNS)",
|
||||
"service_description_avahi-daemon": "允许您使用本地网络中的“ yunohost.local”访问服务器",
|
||||
"service_started": "服务 '{service}' 已启动",
|
||||
"service_start_failed": "无法启动服务 '{service}'\n\n最近的服务日志:{logs}",
|
||||
"service_reloaded_or_restarted": "服务'{service}'已重新加载或重新启动",
|
||||
|
|
|
@ -502,7 +502,7 @@ def app_change_url(operation_logger, app, domain, path):
|
|||
hook_callback("post_app_change_url", env=env_dict)
|
||||
|
||||
|
||||
def app_upgrade(app=[], url=None, file=None, force=False):
|
||||
def app_upgrade(app=[], url=None, file=None, force=False, no_safety_backup=False):
|
||||
"""
|
||||
Upgrade app
|
||||
|
||||
|
@ -510,6 +510,7 @@ def app_upgrade(app=[], url=None, file=None, force=False):
|
|||
file -- Folder or tarball for upgrade
|
||||
app -- App(s) to upgrade (default all)
|
||||
url -- Git url to fetch for upgrade
|
||||
no_safety_backup -- Disable the safety backup during upgrade
|
||||
|
||||
"""
|
||||
from packaging import version
|
||||
|
@ -618,6 +619,7 @@ def app_upgrade(app=[], url=None, file=None, force=False):
|
|||
env_dict["YNH_APP_UPGRADE_TYPE"] = upgrade_type
|
||||
env_dict["YNH_APP_MANIFEST_VERSION"] = str(app_new_version)
|
||||
env_dict["YNH_APP_CURRENT_VERSION"] = str(app_current_version)
|
||||
env_dict["NO_BACKUP_UPGRADE"] = "1" if no_safety_backup else "0"
|
||||
|
||||
# We'll check that the app didn't brutally edit some system configuration
|
||||
manually_modified_files_before_install = manually_modified_files()
|
||||
|
@ -885,7 +887,7 @@ def app_install(
|
|||
raise YunohostValidationError("disk_space_not_sufficient_install")
|
||||
|
||||
# Check ID
|
||||
if "id" not in manifest or "__" in manifest["id"]:
|
||||
if "id" not in manifest or "__" in manifest["id"] or "." in manifest["id"]:
|
||||
raise YunohostValidationError("app_id_invalid")
|
||||
|
||||
app_id = manifest["id"]
|
||||
|
@ -1187,12 +1189,13 @@ def dump_app_log_extract_for_debugging(operation_logger):
|
|||
|
||||
|
||||
@is_unit_operation()
|
||||
def app_remove(operation_logger, app):
|
||||
def app_remove(operation_logger, app, purge=False):
|
||||
"""
|
||||
Remove app
|
||||
|
||||
Keyword argument:
|
||||
Keyword arguments:
|
||||
app -- App(s) to delete
|
||||
purge -- Remove with all app data
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_exec, hook_remove, hook_callback
|
||||
|
@ -1230,6 +1233,7 @@ def app_remove(operation_logger, app):
|
|||
env_dict["YNH_APP_INSTANCE_NAME"] = app
|
||||
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb)
|
||||
env_dict["YNH_APP_MANIFEST_VERSION"] = manifest.get("version", "?")
|
||||
env_dict["YNH_APP_PURGE"] = str(purge)
|
||||
operation_logger.extra.update({"env": env_dict})
|
||||
operation_logger.flush()
|
||||
|
||||
|
@ -1518,7 +1522,7 @@ def app_setting(app, key, value=None, delete=False):
|
|||
# SET
|
||||
else:
|
||||
if key in ["redirected_urls", "redirected_regex"]:
|
||||
value = yaml.load(value)
|
||||
value = yaml.safe_load(value)
|
||||
app_settings[key] = value
|
||||
|
||||
_set_app_settings(app, app_settings)
|
||||
|
@ -2175,7 +2179,7 @@ def _get_app_settings(app_id):
|
|||
)
|
||||
try:
|
||||
with open(os.path.join(APPS_SETTING_PATH, app_id, "settings.yml")) as f:
|
||||
settings = yaml.load(f)
|
||||
settings = yaml.safe_load(f)
|
||||
# If label contains unicode char, this may later trigger issues when building strings...
|
||||
# FIXME: this should be propagated to read_yaml so that this fix applies everywhere I think...
|
||||
settings = {k: v for k, v in settings.items()}
|
||||
|
|
|
@ -166,7 +166,9 @@ def domain_add(operation_logger, domain, dyndns=False):
|
|||
# because it's one of the major service, but in the long term we
|
||||
# should identify the root of this bug...
|
||||
_force_clear_hashes(["/etc/nginx/conf.d/%s.conf" % domain])
|
||||
regen_conf(names=["nginx", "metronome", "dnsmasq", "postfix", "rspamd"])
|
||||
regen_conf(
|
||||
names=["nginx", "metronome", "dnsmasq", "postfix", "rspamd", "mdns"]
|
||||
)
|
||||
app_ssowatconf()
|
||||
|
||||
except Exception as e:
|
||||
|
@ -293,7 +295,7 @@ def domain_remove(operation_logger, domain, remove_apps=False, force=False):
|
|||
"/etc/nginx/conf.d/%s.conf" % domain, new_conf=None, save=True
|
||||
)
|
||||
|
||||
regen_conf(names=["nginx", "metronome", "dnsmasq", "postfix"])
|
||||
regen_conf(names=["nginx", "metronome", "dnsmasq", "postfix", "rspamd", "mdns"])
|
||||
app_ssowatconf()
|
||||
|
||||
hook_callback("post_domain_remove", args=[domain])
|
||||
|
|
|
@ -179,7 +179,7 @@ def firewall_list(raw=False, by_ip_version=False, list_forwarded=False):
|
|||
|
||||
"""
|
||||
with open(FIREWALL_FILE) as f:
|
||||
firewall = yaml.load(f)
|
||||
firewall = yaml.safe_load(f)
|
||||
if raw:
|
||||
return firewall
|
||||
|
||||
|
|
|
@ -444,7 +444,7 @@ def _get_regenconf_infos():
|
|||
"""
|
||||
try:
|
||||
with open(REGEN_CONF_FILE, "r") as f:
|
||||
return yaml.load(f)
|
||||
return yaml.safe_load(f)
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
|
|
|
@ -670,7 +670,7 @@ def _get_services():
|
|||
"""
|
||||
try:
|
||||
with open("/etc/yunohost/services.yml", "r") as f:
|
||||
services = yaml.load(f) or {}
|
||||
services = yaml.safe_load(f) or {}
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
|
|
|
@ -2,4 +2,4 @@ import yaml
|
|||
|
||||
|
||||
def test_yaml_syntax():
|
||||
yaml.load(open("data/actionsmap/yunohost.yml"))
|
||||
yaml.safe_load(open("data/actionsmap/yunohost.yml"))
|
||||
|
|
|
@ -108,7 +108,7 @@ def find_expected_string_keys():
|
|||
yield m
|
||||
|
||||
# Keys for the actionmap ...
|
||||
for category in yaml.load(open("data/actionsmap/yunohost.yml")).values():
|
||||
for category in yaml.safe_load(open("data/actionsmap/yunohost.yml")).values():
|
||||
if "actions" not in category.keys():
|
||||
continue
|
||||
for action in category["actions"].values():
|
||||
|
|
Loading…
Add table
Reference in a new issue