mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge branch 'unstable' into feature224-envvarforscripts
This commit is contained in:
commit
b3cfbc21ac
72 changed files with 2561 additions and 2066 deletions
16
bin/yunohost
16
bin/yunohost
|
@ -5,10 +5,6 @@ import os
|
|||
import sys
|
||||
import argparse
|
||||
|
||||
import moulinette
|
||||
from moulinette.actionsmap import ActionsMap
|
||||
from moulinette.interfaces.cli import colorize, get_locale
|
||||
|
||||
# Either we are in a development environment or not
|
||||
IN_DEVEL = False
|
||||
|
||||
|
@ -35,6 +31,11 @@ if IN_DEVEL:
|
|||
LOG_DIR = os.path.join(basedir, 'log')
|
||||
|
||||
|
||||
import moulinette
|
||||
from moulinette.actionsmap import ActionsMap
|
||||
from moulinette.interfaces.cli import colorize, get_locale
|
||||
|
||||
|
||||
# Initialization & helpers functions -----------------------------------
|
||||
|
||||
def _die(message, title='Error:'):
|
||||
|
@ -50,7 +51,7 @@ def _parse_cli_args():
|
|||
help="Don't use actions map cache",
|
||||
)
|
||||
parser.add_argument('--output-as',
|
||||
choices=['json', 'plain'], default=None,
|
||||
choices=['json', 'plain', 'none'], default=None,
|
||||
help="Output result in another format",
|
||||
)
|
||||
parser.add_argument('--debug',
|
||||
|
@ -149,6 +150,11 @@ def _init_moulinette(debug=False, verbose=False, quiet=False):
|
|||
'handlers': [],
|
||||
'propagate': True,
|
||||
},
|
||||
'moulinette.interface': {
|
||||
'level': level,
|
||||
'handlers': handlers,
|
||||
'propagate': False,
|
||||
},
|
||||
},
|
||||
'root': {
|
||||
'level': level,
|
||||
|
|
|
@ -5,10 +5,6 @@ import os
|
|||
import sys
|
||||
import argparse
|
||||
|
||||
import moulinette
|
||||
from moulinette.actionsmap import ActionsMap
|
||||
from moulinette.interfaces.cli import colorize
|
||||
|
||||
# Either we are in a development environment or not
|
||||
IN_DEVEL = False
|
||||
|
||||
|
@ -39,6 +35,11 @@ if IN_DEVEL:
|
|||
LOG_DIR = os.path.join(basedir, 'log')
|
||||
|
||||
|
||||
import moulinette
|
||||
from moulinette.actionsmap import ActionsMap
|
||||
from moulinette.interfaces.cli import colorize
|
||||
|
||||
|
||||
# Initialization & helpers functions -----------------------------------
|
||||
|
||||
def _die(message, title='Error:'):
|
||||
|
|
77
bin/yunopaste
Executable file
77
bin/yunopaste
Executable file
|
@ -0,0 +1,77 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
PASTE_URL="https://paste.yunohost.org"
|
||||
|
||||
_die() {
|
||||
printf "Error: %s\n" "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
check_dependencies() {
|
||||
curl -V > /dev/null 2>&1 || _die "This script requires curl."
|
||||
}
|
||||
|
||||
paste_data() {
|
||||
json=$(curl -X POST -s -d "$1" "${PASTE_URL}/documents")
|
||||
[[ -z "$json" ]] && _die "Unable to post the data to the server."
|
||||
|
||||
key=$(echo "$json" \
|
||||
| python -c 'import json,sys;o=json.load(sys.stdin);print o["key"]' \
|
||||
2>/dev/null)
|
||||
[[ -z "$key" ]] && _die "Unable to parse the server response."
|
||||
|
||||
echo "${PASTE_URL}/${key}"
|
||||
}
|
||||
|
||||
usage() {
|
||||
printf "Usage: ${0} [OPTION]...
|
||||
|
||||
Read from input stream and paste the data to the YunoHost
|
||||
Haste server.
|
||||
|
||||
For example, to paste the output of the YunoHost diagnosis, you
|
||||
can simply execute the following:
|
||||
yunohost tools diagnosis | ${0}
|
||||
|
||||
It will return the URL where you can access the pasted data.
|
||||
|
||||
Options:
|
||||
-h, --help show this help message and exit
|
||||
"
|
||||
}
|
||||
|
||||
main() {
|
||||
# parse options
|
||||
while (( ${#} )); do
|
||||
case "${1}" in
|
||||
--help|-h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown parameter detected: ${1}" >&2
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
shift 1
|
||||
done
|
||||
|
||||
# check input stream
|
||||
read -t 0 || {
|
||||
echo -e "Invalid usage: No input is provided.\n" >&2
|
||||
usage
|
||||
exit 1
|
||||
}
|
||||
|
||||
paste_data "$(cat)"
|
||||
}
|
||||
|
||||
check_dependencies
|
||||
|
||||
main "${@}"
|
|
@ -516,6 +516,7 @@ app:
|
|||
initdb:
|
||||
action_help: Create database and initialize it with optionnal attached script
|
||||
api: POST /tools/initdb
|
||||
deprecated: true
|
||||
arguments:
|
||||
user:
|
||||
help: Name of the DB user
|
||||
|
@ -956,60 +957,36 @@ service:
|
|||
default: 50
|
||||
type: int
|
||||
|
||||
### service_regenconf()
|
||||
regenconf:
|
||||
action_help: >
|
||||
Regenerate the configuration file(s) for a service and compare the result
|
||||
with the existing configuration file.
|
||||
Prints the differences between files if any.
|
||||
### service_regen_conf()
|
||||
regen-conf:
|
||||
action_help: Regenerate the configuration file(s) for a service
|
||||
api: PUT /services/regenconf
|
||||
configuration:
|
||||
lock: false
|
||||
deprecated_alias:
|
||||
- regenconf
|
||||
arguments:
|
||||
-s:
|
||||
full: --service
|
||||
help: Regenerate configuration for a specfic service
|
||||
-f:
|
||||
full: --force
|
||||
help: Override the current configuration with the newly generated one, even if it has been modified
|
||||
names:
|
||||
help: Services name to regenerate configuration of
|
||||
nargs: "*"
|
||||
metavar: NAME
|
||||
-d:
|
||||
full: --with-diff
|
||||
help: Show differences in case of configuration changes
|
||||
action: store_true
|
||||
|
||||
### service_safecopy()
|
||||
safecopy:
|
||||
action_help: >
|
||||
Check if the specific file has been modified and display differences.
|
||||
Stores the file hash in the services.yml file
|
||||
arguments:
|
||||
new_conf_file:
|
||||
help: Path to the desired conf file
|
||||
conf_file:
|
||||
help: Path to the targeted conf file
|
||||
-s:
|
||||
full: --service
|
||||
help: Service name attached to the conf file
|
||||
extra:
|
||||
required: True
|
||||
-f:
|
||||
full: --force
|
||||
help: Override the current configuration with the newly generated one, even if it has been modified
|
||||
help: >
|
||||
Override all manual modifications in configuration
|
||||
files
|
||||
action: store_true
|
||||
|
||||
### service_saferemove()
|
||||
saferemove:
|
||||
action_help: >
|
||||
Check if the specific file has been modified before removing it.
|
||||
Backup the file in /home/yunohost.backup
|
||||
arguments:
|
||||
conf_file:
|
||||
help: Path to the targeted conf file
|
||||
-s:
|
||||
full: --service
|
||||
help: Service name attached to the conf file
|
||||
extra:
|
||||
required: True
|
||||
-f:
|
||||
full: --force
|
||||
help: Force file deletion
|
||||
-n:
|
||||
full: --dry-run
|
||||
help: Show what would have been regenerated
|
||||
action: store_true
|
||||
-p:
|
||||
full: --list-pending
|
||||
help: List pending configuration files and exit
|
||||
action: store_true
|
||||
|
||||
#############################
|
||||
|
@ -1378,8 +1355,15 @@ hook:
|
|||
nargs: "*"
|
||||
-a:
|
||||
full: --args
|
||||
help: Ordered list of arguments to pass to the script
|
||||
help: Ordered list of arguments to pass to the scripts
|
||||
nargs: "*"
|
||||
-q:
|
||||
full: --no-trace
|
||||
help: Do not print each command that will be executed
|
||||
action: store_true
|
||||
-d:
|
||||
full: --chdir
|
||||
help: The directory from where the scripts will be executed
|
||||
|
||||
### hook_exec()
|
||||
exec:
|
||||
|
@ -1389,7 +1373,8 @@ hook:
|
|||
help: Path of the script to execute
|
||||
-a:
|
||||
full: --args
|
||||
help: Arguments to pass to the script
|
||||
help: Ordered list of arguments to pass to the script
|
||||
nargs: "*"
|
||||
--raise-on-error:
|
||||
help: Raise if the script returns a non-zero exit code
|
||||
action: store_true
|
||||
|
|
|
@ -48,27 +48,33 @@ ynh_package_install() {
|
|||
# usage: ynh_package_install_from_equivs controlfile
|
||||
# | arg: controlfile - path of the equivs control file
|
||||
ynh_package_install_from_equivs() {
|
||||
controlfile=$1
|
||||
|
||||
# install equivs package as needed
|
||||
ynh_package_is_installed 'equivs' \
|
||||
|| ynh_package_install equivs
|
||||
|
||||
# retrieve package information
|
||||
pkgname=$(grep '^Package: ' $1 | cut -d' ' -f 2)
|
||||
pkgversion=$(grep '^Version: ' $1 | cut -d' ' -f 2)
|
||||
pkgname=$(grep '^Package: ' $controlfile | cut -d' ' -f 2)
|
||||
pkgversion=$(grep '^Version: ' $controlfile | cut -d' ' -f 2)
|
||||
[[ -z "$pkgname" || -z "$pkgversion" ]] \
|
||||
&& echo "Invalid control file" && exit 1
|
||||
controlfile=$(readlink -f "$1")
|
||||
|
||||
# update packages cache
|
||||
ynh_package_update
|
||||
|
||||
# build and install the package
|
||||
TMPDIR=$(ynh_mkdir_tmp)
|
||||
(cd $TMPDIR \
|
||||
&& equivs-build "$controlfile" 1>/dev/null \
|
||||
(cp "$controlfile" "${TMPDIR}/control" \
|
||||
&& cd "$TMPDIR" \
|
||||
&& equivs-build ./control 1>/dev/null \
|
||||
&& sudo dpkg --force-depends \
|
||||
-i "./${pkgname}_${pkgversion}_all.deb" 2>&1 \
|
||||
&& sudo apt-get -f -y -qq install) \
|
||||
&& ([[ -n "$TMPDIR" ]] && rm -rf $TMPDIR)
|
||||
|
||||
# check if the package is actually installed
|
||||
ynh_package_is_installed "$pkgname"
|
||||
}
|
||||
|
||||
# Remove package(s)
|
||||
|
|
|
@ -20,6 +20,17 @@ ynh_user_get_info() {
|
|||
sudo yunohost user info "$1" --output-as plain | ynh_get_plain_key "$2"
|
||||
}
|
||||
|
||||
# Get the list of YunoHost users
|
||||
#
|
||||
# example: for u in $(ynh_user_list); do ...
|
||||
#
|
||||
# usage: ynh_user_list
|
||||
# | ret: string - one username per line
|
||||
ynh_user_list() {
|
||||
sudo yunohost user list --output-as plain --quiet \
|
||||
| awk '/^##username$/{getline; print}'
|
||||
}
|
||||
|
||||
# Check if a user exists on the system
|
||||
#
|
||||
# usage: ynh_system_user_exists username
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
backup_dir="$1/conf/ynh/mysql"
|
||||
sudo mkdir -p $backup_dir
|
||||
|
||||
sudo cp -a /etc/yunohost/mysql $backup_dir/
|
||||
sudo cp -a /etc/yunohost/mysql "${backup_dir}/root_pwd"
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
backup_dir="$1/conf/ynh/"
|
||||
backup_dir_legacy="$1/yunohost/"
|
||||
backup_dir="$1/conf/ynh"
|
||||
sudo mkdir -p $backup_dir
|
||||
sudo mkdir -p $backup_dir_legacy
|
||||
|
||||
sudo cp -a /etc/yunohost/current_host $backup_dir
|
||||
sudo cp -a /etc/yunohost/current_host $backup_dir_legacy
|
||||
sudo cp -a /etc/yunohost/current_host "${backup_dir}/current_host"
|
||||
|
|
122
data/hooks/conf_regen/01-yunohost
Normal file → Executable file
122
data/hooks/conf_regen/01-yunohost
Normal file → Executable file
|
@ -1,25 +1,111 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
cd /usr/share/yunohost/templates/yunohost
|
||||
services_path="/etc/yunohost/services.yml"
|
||||
|
||||
sudo mkdir -p /etc/yunohost
|
||||
do_init_regen() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "You must be root to run this script" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f /etc/yunohost/current_host ]; then
|
||||
echo "yunohost.org" | sudo tee /etc/yunohost/current_host
|
||||
fi
|
||||
cd /usr/share/yunohost/templates/yunohost
|
||||
|
||||
if [ ! -f /etc/yunohost/firewall.yml ]; then
|
||||
sudo cp firewall.yml /etc/yunohost/firewall.yml
|
||||
fi
|
||||
[[ -d /etc/yunohost ]] || mkdir -p /etc/yunohost
|
||||
|
||||
if [ ! -f /etc/yunohost/services.yml ]; then
|
||||
sudo cp services.yml /etc/yunohost/services.yml
|
||||
fi
|
||||
# set default current_host
|
||||
[[ -f /etc/yunohost/current_host ]] \
|
||||
|| echo "yunohost.org" > /etc/yunohost/current_host
|
||||
|
||||
# Allow users to access /media directory
|
||||
if [ ! -d /etc/skel/media ]; then
|
||||
mkdir -p /media
|
||||
ln -s /media /etc/skel/
|
||||
fi
|
||||
# copy default services and firewall
|
||||
[[ -f $services_path ]] \
|
||||
|| cp services.yml "$services_path"
|
||||
[[ -f /etc/yunohost/firewall.yml ]] \
|
||||
|| cp firewall.yml /etc/yunohost/firewall.yml
|
||||
|
||||
# allow users to access /media directory
|
||||
[[ -d /etc/skel/media ]] \
|
||||
|| (mkdir -p /media && ln -s /media /etc/skel/media)
|
||||
}
|
||||
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/yunohost
|
||||
|
||||
# update services.yml
|
||||
if [[ -f $services_path ]]; then
|
||||
tmp_services_path="${services_path}-tmp"
|
||||
new_services_path="${services_path}-new"
|
||||
sudo cp "$services_path" "$tmp_services_path"
|
||||
_update_services "$new_services_path" || {
|
||||
sudo mv "$tmp_services_path" "$services_path"
|
||||
exit 1
|
||||
}
|
||||
if [[ -f $new_services_path ]]; then
|
||||
# replace services.yml with new one
|
||||
sudo mv "$new_services_path" "$services_path"
|
||||
sudo mv "$tmp_services_path" "${services_path}-old"
|
||||
else
|
||||
sudo rm -f "$tmp_services_path"
|
||||
fi
|
||||
else
|
||||
sudo cp services.yml /etc/yunohost/services.yml
|
||||
fi
|
||||
}
|
||||
|
||||
_update_services() {
|
||||
sudo python2 - << EOF
|
||||
import yaml
|
||||
with open('services.yml') as f:
|
||||
new_services = yaml.load(f)
|
||||
with open('/etc/yunohost/services.yml') as f:
|
||||
services = yaml.load(f)
|
||||
updated = False
|
||||
for service, conf in new_services.items():
|
||||
# remove service with empty conf
|
||||
if not conf:
|
||||
if service in services:
|
||||
print("removing '{0}' from services".format(service))
|
||||
del services[service]
|
||||
updated = True
|
||||
# add new service
|
||||
elif not services.get(service, None):
|
||||
print("adding '{0}' to services".format(service))
|
||||
services[service] = conf
|
||||
updated = True
|
||||
# update service conf
|
||||
else:
|
||||
conffiles = services[service].pop('conffiles', {})
|
||||
if services[service] != conf:
|
||||
print("update '{0}' service".format(service))
|
||||
services[service].update(conf)
|
||||
updated = True
|
||||
if conffiles:
|
||||
services[service]['conffiles'] = conffiles
|
||||
if updated:
|
||||
with open('/etc/yunohost/services.yml-new', 'w') as f:
|
||||
yaml.safe_dump(services, f, default_flow_style=False)
|
||||
EOF
|
||||
}
|
||||
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
case "$1" in
|
||||
pre)
|
||||
do_pre_regen $4
|
||||
;;
|
||||
post)
|
||||
;;
|
||||
init)
|
||||
do_init_regen
|
||||
;;
|
||||
*)
|
||||
echo "hook called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
|
135
data/hooks/conf_regen/02-ssl
Normal file → Executable file
135
data/hooks/conf_regen/02-ssl
Normal file → Executable file
|
@ -1,64 +1,93 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [ ! -f /etc/yunohost/installed ]; then
|
||||
sudo cp $1 $2
|
||||
else
|
||||
if [ $force ]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s ssl $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s ssl $1 $2
|
||||
fi
|
||||
fi
|
||||
ssl_dir="/usr/share/yunohost/yunohost-config/ssl/yunoCA"
|
||||
|
||||
do_init_regen() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "You must be root to run this script" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# create certs and SSL directories
|
||||
mkdir -p "/etc/yunohost/certs/yunohost.org"
|
||||
mkdir -p "${ssl_dir}/"{ca,certs,crl,newcerts}
|
||||
|
||||
# initialize some files
|
||||
[[ -f "${ssl_dir}/serial" ]] \
|
||||
|| echo "00" > "${ssl_dir}/serial"
|
||||
[[ -f "${ssl_dir}/index.txt" ]] \
|
||||
|| touch "${ssl_dir}/index.txt"
|
||||
|
||||
openssl_conf="/usr/share/yunohost/templates/ssl/openssl.cnf"
|
||||
|
||||
# create default certificates
|
||||
if [[ ! -f /etc/yunohost/certs/yunohost.org/ca.pem ]]; then
|
||||
openssl req -x509 -new -config "$openssl_conf" \
|
||||
-days 3650 -out "${ssl_dir}/ca/cacert.pem" \
|
||||
-keyout "${ssl_dir}/ca/cakey.pem" -nodes -batch 2>&1
|
||||
cp "${ssl_dir}/ca/cacert.pem" \
|
||||
/etc/yunohost/certs/yunohost.org/ca.pem
|
||||
ln -sf /etc/yunohost/certs/yunohost.org/ca.pem \
|
||||
/etc/ssl/certs/ca-yunohost_crt.pem
|
||||
update-ca-certificates
|
||||
fi
|
||||
|
||||
if [[ ! -f /etc/yunohost/certs/yunohost.org/crt.pem ]]; then
|
||||
openssl req -new -config "$openssl_conf" \
|
||||
-days 730 -out "${ssl_dir}/certs/yunohost_csr.pem" \
|
||||
-keyout "${ssl_dir}/certs/yunohost_key.pem" -nodes -batch 2>&1
|
||||
openssl ca -config "$openssl_conf" \
|
||||
-days 730 -in "${ssl_dir}/certs/yunohost_csr.pem" \
|
||||
-out "${ssl_dir}/certs/yunohost_crt.pem" -batch 2>&1
|
||||
|
||||
last_cert=$(ls $ssl_dir/newcerts/*.pem | sort -V | tail -n 1)
|
||||
chmod 640 "${ssl_dir}/certs/yunohost_key.pem"
|
||||
chmod 640 "$last_cert"
|
||||
|
||||
cp "${ssl_dir}/certs/yunohost_key.pem" \
|
||||
/etc/yunohost/certs/yunohost.org/key.pem
|
||||
cp "$last_cert" \
|
||||
/etc/yunohost/certs/yunohost.org/crt.pem
|
||||
ln -sf /etc/yunohost/certs/yunohost.org/crt.pem \
|
||||
/etc/ssl/certs/yunohost_crt.pem
|
||||
ln -sf /etc/yunohost/certs/yunohost.org/key.pem \
|
||||
/etc/ssl/private/yunohost_key.pem
|
||||
fi
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/ssl
|
||||
ssl_dir=/usr/share/yunohost/yunohost-config/ssl/yunoCA
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
sudo mkdir -p /etc/yunohost/certs/yunohost.org
|
||||
sudo mkdir -p $ssl_dir/{ca,certs,crl,newcerts}
|
||||
cd /usr/share/yunohost/templates/ssl
|
||||
|
||||
safe_copy openssl.cnf $ssl_dir/openssl.cnf
|
||||
install -D -m 644 openssl.cnf "${pending_dir}/${ssl_dir}/openssl.cnf"
|
||||
}
|
||||
|
||||
[ -f $ssl_dir/serial ] \
|
||||
|| (echo "00" | sudo tee $ssl_dir/serial)
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
[ -f $ssl_dir/index.txt ] \
|
||||
|| sudo touch $ssl_dir/index.txt
|
||||
# TODO: regenerate certificates if conf changed?
|
||||
}
|
||||
|
||||
if [ ! -f /etc/yunohost/certs/yunohost.org/ca.pem ]; then
|
||||
sudo openssl req -x509 -new -config $ssl_dir/openssl.cnf \
|
||||
-days 3650 -out $ssl_dir/ca/cacert.pem \
|
||||
-keyout $ssl_dir/ca/cakey.pem -nodes -batch
|
||||
sudo cp $ssl_dir/ca/cacert.pem \
|
||||
/etc/yunohost/certs/yunohost.org/ca.pem
|
||||
sudo ln -sf /etc/yunohost/certs/yunohost.org/ca.pem \
|
||||
/etc/ssl/certs/ca-yunohost_crt.pem
|
||||
sudo update-ca-certificates
|
||||
fi
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
if [ ! -f /etc/yunohost/certs/yunohost.org/crt.pem ]; then
|
||||
sudo openssl req -new -config $ssl_dir/openssl.cnf \
|
||||
-days 730 -out $ssl_dir/certs/yunohost_csr.pem \
|
||||
-keyout $ssl_dir/certs/yunohost_key.pem -nodes -batch
|
||||
sudo openssl ca -config $ssl_dir/openssl.cnf \
|
||||
-days 730 -in $ssl_dir/certs/yunohost_csr.pem \
|
||||
-out $ssl_dir/certs/yunohost_crt.pem -batch
|
||||
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
|
||||
|
||||
last_cert=$(ls $ssl_dir/newcerts/*.pem | sort -V | tail -n 1)
|
||||
sudo chmod 640 $ssl_dir/certs/yunohost_key.pem
|
||||
sudo chmod 640 $last_cert
|
||||
|
||||
sudo cp $ssl_dir/certs/yunohost_key.pem \
|
||||
/etc/yunohost/certs/yunohost.org/key.pem
|
||||
sudo cp $last_cert \
|
||||
/etc/yunohost/certs/yunohost.org/crt.pem
|
||||
sudo ln -sf /etc/yunohost/certs/yunohost.org/crt.pem \
|
||||
/etc/ssl/certs/yunohost_crt.pem
|
||||
sudo ln -sf /etc/yunohost/certs/yunohost.org/key.pem \
|
||||
/etc/ssl/private/yunohost_key.pem
|
||||
fi
|
||||
exit 0
|
||||
|
|
63
data/hooks/conf_regen/03-ssh
Normal file → Executable file
63
data/hooks/conf_regen/03-ssh
Normal file → Executable file
|
@ -1,30 +1,45 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [ $force ]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s ssh \
|
||||
$1 $2 \
|
||||
--force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s ssh \
|
||||
$1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/ssh
|
||||
|
||||
# only overwrite SSH configuration on an ISO installation
|
||||
if [[ ! -f /etc/yunohost/from_script ]]; then
|
||||
# do not listen to IPv6 if unavailable
|
||||
[[ -f /proc/net/if_inet6 ]] \
|
||||
|| sed -i "s/ListenAddress ::/#ListenAddress ::/g" sshd_config
|
||||
|
||||
install -D -m 644 sshd_config "${pending_dir}/etc/ssh/sshd_config"
|
||||
fi
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/ssh
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
# Only overwrite SSH configuration on an ISO installation
|
||||
if [ ! -f /etc/yunohost/from_script ]; then
|
||||
if [[ ! -f /etc/yunohost/from_script ]]; then
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service ssh restart
|
||||
fi
|
||||
}
|
||||
|
||||
# Do not listen to IPv6 if unavailable
|
||||
if [ ! -f /proc/net/if_inet6 ]; then
|
||||
sudo sed -i "s/ListenAddress ::/#ListenAddress ::/g" sshd_config
|
||||
fi
|
||||
safe_copy sshd_config /etc/ssh/sshd_config
|
||||
|
||||
sudo service ssh restart
|
||||
fi
|
||||
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
|
||||
|
|
165
data/hooks/conf_regen/06-slapd
Normal file → Executable file
165
data/hooks/conf_regen/06-slapd
Normal file → Executable file
|
@ -1,71 +1,118 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [ ! -f /etc/yunohost/installed ]; then
|
||||
sudo cp $1 $2
|
||||
else
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s slapd $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s slapd $1 $2
|
||||
fi
|
||||
fi
|
||||
do_init_regen() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "You must be root to run this script" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
do_pre_regen ""
|
||||
|
||||
# fix some permissions
|
||||
chown root:openldap /etc/ldap/slapd.conf
|
||||
chown -R openldap:openldap /etc/ldap/schema/
|
||||
|
||||
# check the slapd config file at first
|
||||
slaptest -Q -u -f /etc/ldap/slapd.conf
|
||||
|
||||
# regenerate LDAP config directory from slapd.conf
|
||||
rm -Rf /etc/ldap/slapd.d
|
||||
mkdir /etc/ldap/slapd.d
|
||||
slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/ 2>&1
|
||||
chown -R openldap:openldap /etc/ldap/slapd.d/
|
||||
|
||||
service slapd restart
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/slapd
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
# Remove legacy configuration file
|
||||
[ ! -f /etc/yunohost/installed ] \
|
||||
|| sudo yunohost service saferemove -s slapd \
|
||||
/etc/ldap/slapd-yuno.conf
|
||||
cd /usr/share/yunohost/templates/slapd
|
||||
|
||||
# Retrieve current backend
|
||||
backend=$(sudo slapcat -n 0 | sed -n 's/^dn: olcDatabase={1}\(.*\),cn=config$/\1/p')
|
||||
# remove legacy configuration file
|
||||
[ ! -f /etc/ldap/slapd-yuno.conf ] \
|
||||
|| touch "${pending_dir}/etc/ldap/slapd-yuno.conf"
|
||||
|
||||
# Save current database in case of a backend change
|
||||
BACKEND_CHANGE=0
|
||||
BACKUP_DIR="/var/backups/dc=yunohost,dc=org-${backend}-$(date +%s)"
|
||||
if [[ -n "$backend" && "$backend" != "mdb" && "$force" == "True" ]]; then
|
||||
BACKEND_CHANGE=1
|
||||
sudo mkdir -p "$BACKUP_DIR"
|
||||
sudo slapcat -b dc=yunohost,dc=org \
|
||||
-l "${BACKUP_DIR}/dc=yunohost-dc=org.ldif"
|
||||
fi
|
||||
# create needed directories
|
||||
ldap_dir="${pending_dir}/etc/ldap"
|
||||
schema_dir="${ldap_dir}/schema"
|
||||
mkdir -p "$ldap_dir" "$schema_dir"
|
||||
|
||||
safe_copy sudo.schema /etc/ldap/schema/sudo.schema
|
||||
safe_copy mailserver.schema /etc/ldap/schema/mailserver.schema
|
||||
safe_copy ldap.conf /etc/ldap/ldap.conf
|
||||
safe_copy slapd.default /etc/default/slapd
|
||||
safe_copy slapd.conf /etc/ldap/slapd.conf
|
||||
# copy configuration files
|
||||
cp -a ldap.conf slapd.conf "$ldap_dir"
|
||||
cp -a sudo.schema mailserver.schema "$schema_dir"
|
||||
|
||||
# Fix some permissions
|
||||
sudo chown root:openldap /etc/ldap/slapd.conf
|
||||
sudo chown -R openldap:openldap /etc/ldap/schema/
|
||||
sudo chown -R openldap:openldap /etc/ldap/slapd.d/
|
||||
install -D -m 644 slapd.default "${pending_dir}/etc/default/slapd"
|
||||
}
|
||||
|
||||
# Check the slapd config file at first
|
||||
sudo slaptest -Q -u -f /etc/ldap/slapd.conf
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
if [[ $BACKEND_CHANGE -eq 1 ]]; then
|
||||
# Regenerate LDAP config directory and import database as root
|
||||
# since the admin user may be unavailable
|
||||
sudo sh -c "rm -Rf /etc/ldap/slapd.d;
|
||||
mkdir /etc/ldap/slapd.d;
|
||||
slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d;
|
||||
chown -R openldap:openldap /etc/ldap/slapd.d;
|
||||
slapadd -F /etc/ldap/slapd.d -b dc=yunohost,dc=org \
|
||||
-l '${BACKUP_DIR}/dc=yunohost-dc=org.ldif';
|
||||
chown -R openldap:openldap /var/lib/ldap" 2>&1
|
||||
else
|
||||
# Regenerate LDAP config directory from slapd.conf
|
||||
sudo rm -Rf /etc/ldap/slapd.d
|
||||
sudo mkdir /etc/ldap/slapd.d
|
||||
sudo slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/ 2>&1
|
||||
sudo chown -R openldap:openldap /etc/ldap/slapd.d/
|
||||
fi
|
||||
# fix some permissions
|
||||
sudo chown root:openldap /etc/ldap/slapd.conf
|
||||
sudo chown -R openldap:openldap /etc/ldap/schema/
|
||||
sudo chown -R openldap:openldap /etc/ldap/slapd.d/
|
||||
|
||||
sudo service slapd force-reload
|
||||
[ -z "$regen_conf_files" ] && exit 0
|
||||
|
||||
# retrieve current and new backends
|
||||
curr_backend=$(sudo slapcat -n 0 \
|
||||
| sed -n 's/^dn: olcDatabase={1}\(.*\),cn=config$/\1/p')
|
||||
new_backend=$(grep '^database' /etc/ldap/slapd.conf | awk '{print $2}')
|
||||
|
||||
# save current database in case of a backend change
|
||||
backend_change=0
|
||||
backup_dir="/var/backups/dc=yunohost,dc=org-${curr_backend}-$(date +%s)"
|
||||
if [[ -n "$curr_backend" && "$curr_backend" != "$new_backend" ]]; then
|
||||
backend_change=1
|
||||
sudo mkdir -p "$backup_dir"
|
||||
sudo slapcat -b dc=yunohost,dc=org \
|
||||
-l "${backup_dir}/dc=yunohost-dc=org.ldif"
|
||||
fi
|
||||
|
||||
# check the slapd config file at first
|
||||
sudo slaptest -Q -u -f /etc/ldap/slapd.conf
|
||||
|
||||
if [[ $backend_change -eq 1 ]]; then
|
||||
# regenerate LDAP config directory and import database as root
|
||||
# since the admin user may be unavailable
|
||||
sudo sh -c "rm -Rf /etc/ldap/slapd.d;
|
||||
mkdir /etc/ldap/slapd.d;
|
||||
slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d;
|
||||
chown -R openldap:openldap /etc/ldap/slapd.d;
|
||||
slapadd -F /etc/ldap/slapd.d -b dc=yunohost,dc=org \
|
||||
-l '${backup_dir}/dc=yunohost-dc=org.ldif';
|
||||
chown -R openldap:openldap /var/lib/ldap" 2>&1
|
||||
else
|
||||
# regenerate LDAP config directory from slapd.conf
|
||||
sudo rm -Rf /etc/ldap/slapd.d
|
||||
sudo mkdir /etc/ldap/slapd.d
|
||||
sudo slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/ 2>&1
|
||||
sudo chown -R openldap:openldap /etc/ldap/slapd.d/
|
||||
fi
|
||||
|
||||
sudo service slapd force-reload
|
||||
}
|
||||
|
||||
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
|
||||
|
|
48
data/hooks/conf_regen/09-nslcd
Normal file → Executable file
48
data/hooks/conf_regen/09-nslcd
Normal file → Executable file
|
@ -1,26 +1,36 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s nslcd \
|
||||
$1 $2 \
|
||||
--force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s nslcd \
|
||||
$1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/nslcd
|
||||
|
||||
install -D -m 644 nslcd.conf "${pending_dir}/etc/nslcd.conf"
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/nslcd
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
safe_copy nslcd.conf /etc/nslcd.conf
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service nslcd restart
|
||||
}
|
||||
|
||||
# Fix: Add a blank line at the end of the file
|
||||
# to avoid nscld restart failure
|
||||
echo -e "\n" | sudo tee -a /etc/nslcd.conf
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
sudo service nslcd restart
|
||||
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
|
||||
|
|
120
data/hooks/conf_regen/12-metronome
Normal file → Executable file
120
data/hooks/conf_regen/12-metronome
Normal file → Executable file
|
@ -1,66 +1,76 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s metronome \
|
||||
$1 $2 \
|
||||
--force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s metronome \
|
||||
$1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/metronome
|
||||
|
||||
# create directories for pending conf
|
||||
metronome_dir="${pending_dir}/etc/metronome"
|
||||
metronome_conf_dir="${metronome_dir}/conf.d"
|
||||
mkdir -p "$metronome_conf_dir"
|
||||
|
||||
# retrieve variables
|
||||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
||||
|
||||
# install main conf file
|
||||
cat metronome.cfg.lua \
|
||||
| sed "s/{{ main_domain }}/${main_domain}/g" \
|
||||
> "${metronome_dir}/metronome.cfg.lua"
|
||||
|
||||
# add domain conf files
|
||||
for domain in $domain_list; do
|
||||
cat domain.tpl.cfg.lua \
|
||||
| sed "s/{{ domain }}/${domain}/g" \
|
||||
> "${metronome_conf_dir}/${domain}.cfg.lua"
|
||||
done
|
||||
|
||||
# remove old domain conf files
|
||||
conf_files=$(ls -1 /etc/metronome/conf.d \
|
||||
| awk '/^[^\.]+\.[^\.]+.*\.cfg\.lua$/ { print $1 }')
|
||||
for file in $conf_files; do
|
||||
domain=${file%.cfg.lua}
|
||||
[[ $domain_list =~ $domain ]] \
|
||||
|| touch "${metronome_conf_dir}/${file}"
|
||||
done
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/metronome
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
# Copy configuration files
|
||||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
cat metronome.cfg.lua.sed \
|
||||
| sed "s/{{ main_domain }}/$main_domain/g" \
|
||||
| sudo tee metronome.cfg.lua
|
||||
safe_copy metronome.cfg.lua /etc/metronome/metronome.cfg.lua
|
||||
# fix some permissions
|
||||
sudo chown -R metronome: /var/lib/metronome/
|
||||
sudo chown -R metronome: /etc/metronome/conf.d/
|
||||
|
||||
need_restart=False
|
||||
sudo mkdir -p /etc/metronome/conf.d
|
||||
# retrieve variables
|
||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
||||
|
||||
domain_list=$(sudo yunohost domain list --output-as plain)
|
||||
# create metronome directories for domains
|
||||
for domain in $domain_list; do
|
||||
sudo mkdir -p "/var/lib/metronome/${domain//./%2e}/pep"
|
||||
done
|
||||
|
||||
# Copy a configuration file for each YunoHost domain
|
||||
for domain in $domain_list; do
|
||||
sanitzed_domain="$(echo $domain | sed 's/\./%2e/g')"
|
||||
sudo mkdir -p /var/lib/metronome/$sanitzed_domain/pep
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service metronome restart
|
||||
}
|
||||
|
||||
cat domain.cfg.lua.sed \
|
||||
| sed "s/{{ domain }}/$domain/g" \
|
||||
| sudo tee $domain.cfg.lua
|
||||
if [[ $(safe_copy $domain.cfg.lua /etc/metronome/conf.d/$domain.cfg.lua | tail -n1) == "True" ]]; then
|
||||
need_restart=True
|
||||
fi
|
||||
done
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
# Remove old domains files
|
||||
for file in /etc/metronome/conf.d/*; do
|
||||
domain=$(echo $file \
|
||||
| sed 's|/etc/metronome/conf.d/||' \
|
||||
| sed 's|.cfg.lua||')
|
||||
sanitzed_domain="$(echo $domain | sed 's/\./%2e/g')"
|
||||
[[ $domain_list =~ $domain ]] \
|
||||
|| ([[ $(sudo yunohost service saferemove -s metronome $file | tail -n1) == "True" ]] \
|
||||
&& sudo rm -rf /var/lib/metronome/$sanitzed_domain)
|
||||
done
|
||||
case "$1" in
|
||||
pre)
|
||||
do_pre_regen $4
|
||||
;;
|
||||
post)
|
||||
do_post_regen $4
|
||||
;;
|
||||
*)
|
||||
echo "hook called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Create domain directory
|
||||
sudo chown -R metronome: /var/lib/metronome/
|
||||
sudo chown -R metronome: /etc/metronome/conf.d/
|
||||
|
||||
# Restart if need be
|
||||
if [[ "$need_restart" == "True" ]]; then
|
||||
sudo service metronome restart
|
||||
else
|
||||
sudo service metronome reload \
|
||||
|| sudo service metronome restart
|
||||
fi
|
||||
exit 0
|
||||
|
|
153
data/hooks/conf_regen/15-nginx
Normal file → Executable file
153
data/hooks/conf_regen/15-nginx
Normal file → Executable file
|
@ -1,86 +1,101 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [ ! -f /etc/yunohost/installed ]; then
|
||||
sudo cp $1 $2
|
||||
else
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s nginx \
|
||||
$1 $2 \
|
||||
--force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s nginx \
|
||||
$1 $2
|
||||
fi
|
||||
fi
|
||||
do_init_regen() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "You must be root to run this script" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
do_pre_regen ""
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/nginx
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
# Copy plain single configuration files
|
||||
files="ssowat.conf
|
||||
global.conf
|
||||
yunohost_admin.conf
|
||||
yunohost_admin.conf.inc
|
||||
yunohost_api.conf.inc
|
||||
yunohost_panel.conf.inc"
|
||||
cd /usr/share/yunohost/templates/nginx
|
||||
|
||||
for file in $files; do
|
||||
safe_copy $file /etc/nginx/conf.d/$file
|
||||
done
|
||||
nginx_dir="${pending_dir}/etc/nginx"
|
||||
nginx_conf_dir="${nginx_dir}/conf.d"
|
||||
mkdir -p "$nginx_conf_dir"
|
||||
|
||||
# install plain conf files
|
||||
cp plain/* "$nginx_conf_dir"
|
||||
|
||||
if [ -f /etc/yunohost/installed ]; then
|
||||
# probably run with init: just disable default site, restart NGINX and exit
|
||||
if [[ -z "$pending_dir" ]]; then
|
||||
rm -f "${nginx_dir}/sites-enabled/default"
|
||||
service nginx restart
|
||||
exit 0
|
||||
fi
|
||||
|
||||
need_restart=False
|
||||
domain_list=$(sudo yunohost domain list --output-as plain)
|
||||
# retrieve variables
|
||||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
||||
|
||||
# Copy a configuration file for each YunoHost domain
|
||||
for domain in $domain_list; do
|
||||
sudo mkdir -p /etc/nginx/conf.d/$domain.d
|
||||
cat server.conf.sed \
|
||||
| sed "s/{{ domain }}/$domain/g" \
|
||||
| sudo tee $domain.conf
|
||||
[[ $(safe_copy $domain.conf /etc/nginx/conf.d/$domain.conf | tail -n1) == "True" ]] \
|
||||
&& need_restart=True
|
||||
# add domain conf files
|
||||
for domain in $domain_list; do
|
||||
domain_conf_dir="${nginx_conf_dir}/${domain}.d"
|
||||
mkdir -p "$domain_conf_dir"
|
||||
|
||||
[ -f /etc/nginx/conf.d/$domain.d/yunohost_local.conf ] \
|
||||
&& [[ $main_domain != $domain ]] \
|
||||
&& sudo yunohost service saferemove -s nginx \
|
||||
/etc/nginx/conf.d/$domain.d/yunohost_local.conf
|
||||
done
|
||||
# NGINX server configuration
|
||||
cat server.tpl.conf \
|
||||
| sed "s/{{ domain }}/${domain}/g" \
|
||||
> "${nginx_conf_dir}/${domain}.conf"
|
||||
|
||||
[[ $main_domain != $domain ]] \
|
||||
&& touch "${domain_conf_dir}/yunohost_local.conf" \
|
||||
|| cp yunohost_local.conf "${domain_conf_dir}/yunohost_local.conf"
|
||||
done
|
||||
|
||||
# Copy 'yunohost.local' to the main domain conf directory
|
||||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
safe_copy yunohost_local.conf \
|
||||
/etc/nginx/conf.d/$main_domain.d/yunohost_local.conf
|
||||
# remove old domain conf files
|
||||
conf_files=$(ls -1 /etc/nginx/conf.d \
|
||||
| awk '/^[^\.]+\.[^\.]+.*\.conf$/ { print $1 }')
|
||||
for file in $conf_files; do
|
||||
domain=${file%.conf}
|
||||
[[ $domain_list =~ $domain ]] \
|
||||
|| touch "${nginx_conf_dir}/${file}"
|
||||
done
|
||||
|
||||
# disable default site
|
||||
mkdir -p "${nginx_dir}/sites-enabled"
|
||||
touch "${nginx_dir}/sites-enabled/default"
|
||||
}
|
||||
|
||||
# Remove old domains files
|
||||
for file in /etc/nginx/conf.d/*.*.conf; do
|
||||
domain=$(echo $file \
|
||||
| sed 's|/etc/nginx/conf.d/||' \
|
||||
| sed 's|.conf||')
|
||||
[[ $domain_list =~ $domain ]] \
|
||||
|| ([[ $(sudo yunohost service saferemove -s nginx $file) == "True" ]] \
|
||||
&& (sudo rm -r /etc/nginx/conf.d/$domain.d || true))
|
||||
done
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
else
|
||||
[ ! -f /etc/nginx/sites-available/default ] \
|
||||
|| sudo rm -f /etc/nginx/sites-enabled/default
|
||||
need_restart=True
|
||||
fi
|
||||
[ -z "$regen_conf_files" ] && exit 0
|
||||
|
||||
# Restart if need be
|
||||
if [[ "$need_restart" == "True" ]]; then
|
||||
sudo service nginx restart
|
||||
else
|
||||
sudo service nginx reload \
|
||||
|| sudo service nginx restart
|
||||
fi
|
||||
# retrieve variables
|
||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
||||
|
||||
# create NGINX conf directories for domains
|
||||
for domain in $domain_list; do
|
||||
sudo mkdir -p "/etc/nginx/conf.d/${domain}.d"
|
||||
done
|
||||
|
||||
sudo service nginx restart
|
||||
}
|
||||
|
||||
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
|
||||
|
|
96
data/hooks/conf_regen/19-postfix
Normal file → Executable file
96
data/hooks/conf_regen/19-postfix
Normal file → Executable file
|
@ -1,56 +1,56 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s postfix \
|
||||
$1 $2 \
|
||||
--force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s postfix \
|
||||
$1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/postfix
|
||||
|
||||
postfix_dir="${pending_dir}/etc/postfix"
|
||||
mkdir -p "$postfix_dir"
|
||||
|
||||
# install plain conf files
|
||||
cp plain/* "$postfix_dir"
|
||||
|
||||
# prepare main.cf conf file
|
||||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
cat main.cf \
|
||||
| sed "s/{{ main_domain }}/${main_domain}/g" \
|
||||
> "${postfix_dir}/main.cf"
|
||||
|
||||
# adapt it for IPv4-only hosts
|
||||
if [ ! -f /proc/net/if_inet6 ]; then
|
||||
sed -i \
|
||||
's/ \[::ffff:127.0.0.0\]\/104 \[::1\]\/128//g' \
|
||||
"${postfix_dir}/main.cf"
|
||||
sed -i \
|
||||
's/inet_interfaces = all/&\ninet_protocols = ipv4/' \
|
||||
"${postfix_dir}/main.cf"
|
||||
fi
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/postfix
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
# Copy plain single configuration files
|
||||
files="header_checks
|
||||
ldap-accounts.cf
|
||||
ldap-aliases.cf
|
||||
ldap-domains.cf
|
||||
master.cf
|
||||
sender_canonical
|
||||
smtp_reply_filter"
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service postfix restart
|
||||
}
|
||||
|
||||
for file in $files; do
|
||||
safe_copy $file /etc/postfix/$file
|
||||
done
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
case "$1" in
|
||||
pre)
|
||||
do_pre_regen $4
|
||||
;;
|
||||
post)
|
||||
do_post_regen $4
|
||||
;;
|
||||
*)
|
||||
echo "hook called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Replace main domain in the main configuration file
|
||||
cat main.cf.sed \
|
||||
| sed "s/{{ main_domain }}/$main_domain/g" \
|
||||
| sudo tee main.cf
|
||||
|
||||
# And adapt it to IPv4-only hosts
|
||||
if [ ! -f /proc/net/if_inet6 ]; then
|
||||
sudo sed -i \
|
||||
's/ \[::ffff:127.0.0.0\]\/104 \[::1\]\/128//g' \
|
||||
main.cf
|
||||
|
||||
sudo sed -i \
|
||||
's/inet_interfaces = all/inet_interfaces = all\ninet_protocols = ipv4/' \
|
||||
main.cf
|
||||
fi
|
||||
|
||||
if [[ $(safe_copy main.cf /etc/postfix/main.cf) == "True" ]]; then
|
||||
sudo service postfix restart
|
||||
else
|
||||
sudo service postfix reload \
|
||||
|| sudo service postfix restart
|
||||
fi
|
||||
exit 0
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
set -e
|
||||
|
||||
# Execute this hook only if we force the configuration regeneration
|
||||
if [[ "$1" == "True" ]]; then
|
||||
|
||||
# Add new email services
|
||||
sudo yunohost service add rspamd -l /var/log/mail.log \
|
||||
|| echo "rspamd is already listed in services"
|
||||
|
||||
sudo yunohost service add rmilter -l /var/log/mail.log \
|
||||
|| echo "rmilter is already listed in services"
|
||||
|
||||
sudo yunohost service add redis-server -l /var/log/redis/redis-server.log \
|
||||
|| echo "redis-server is already listed in services"
|
||||
|
||||
# Remove previous email services
|
||||
systemctl is-enabled spamassassin > /dev/null 2>&1 \
|
||||
&& sudo systemctl disable spamassassin
|
||||
systemctl is-active spamassassin > /dev/null \
|
||||
&& sudo systemctl stop spamassassin
|
||||
sudo rm -f /etc/cron.daily/spamassassin
|
||||
sudo yunohost service status spamassassin > /dev/null 2>&1 \
|
||||
&& sudo yunohost service remove spamassassin
|
||||
|
||||
# 'systemctl is-enabled' does not work for service with no systemd unit file
|
||||
sudo ls /etc/rc2.d/S??amavis > /dev/null 2>&1 \
|
||||
|| sudo systemctl disable amavis
|
||||
sudo systemctl is-active amavis > /dev/null \
|
||||
&& sudo systemctl stop amavis
|
||||
sudo yunohost service status amavis > /dev/null 2>&1 \
|
||||
&& sudo yunohost service remove amavis
|
||||
|
||||
# 'systemctl is-enabled' does not work for service with no systemd unit file
|
||||
sudo ls /etc/rc2.d/S??postgrey > /dev/null 2>&1 \
|
||||
|| sudo systemctl disable postgrey
|
||||
sudo systemctl is-active postgrey > /dev/null \
|
||||
&& sudo systemctl stop postgrey
|
||||
sudo yunohost service status postgrey > /dev/null 2>&1 \
|
||||
&& sudo yunohost service remove postgrey
|
||||
|
||||
fi
|
||||
|
||||
exit 0
|
96
data/hooks/conf_regen/25-dovecot
Normal file → Executable file
96
data/hooks/conf_regen/25-dovecot
Normal file → Executable file
|
@ -1,51 +1,69 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s dovecot $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s dovecot $1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/dovecot
|
||||
|
||||
dovecot_dir="${pending_dir}/etc/dovecot"
|
||||
mkdir -p "${dovecot_dir}/global_script"
|
||||
|
||||
# copy simple conf files
|
||||
cp dovecot-ldap.conf "${dovecot_dir}/dovecot-ldap.conf"
|
||||
cp dovecot.sieve "${dovecot_dir}/global_script/dovecot.sieve"
|
||||
|
||||
# prepare dovecot.conf conf file
|
||||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
cat dovecot.conf \
|
||||
| sed "s/{{ main_domain }}/${main_domain}/g" \
|
||||
> "${dovecot_dir}/dovecot.conf"
|
||||
|
||||
# adapt it for IPv4-only hosts
|
||||
if [ ! -f /proc/net/if_inet6 ]; then
|
||||
sed -i \
|
||||
's/^\(listen =\).*/\1 */' \
|
||||
"${dovecot_dir}/dovecot.conf"
|
||||
fi
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/dovecot
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
# Create vmail user
|
||||
sudo id vmail > /dev/null 2>&1 \
|
||||
|| sudo adduser --system --ingroup mail --uid 500 vmail
|
||||
# create vmail user
|
||||
id vmail > /dev/null 2>&1 \
|
||||
|| sudo adduser --system --ingroup mail --uid 500 vmail
|
||||
|
||||
# fix permissions
|
||||
sudo chown -R vmail:mail /etc/dovecot/global_script
|
||||
sudo chmod 770 /etc/dovecot/global_script
|
||||
|
||||
# Replace main domain in the main configuration file
|
||||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
cat dovecot.conf.sed \
|
||||
| sed "s/{{ main_domain }}/$main_domain/g" \
|
||||
| sudo tee dovecot.conf
|
||||
[ -z "$regen_conf_files" ] && exit 0
|
||||
|
||||
# compile sieve script
|
||||
[[ "$regen_conf_files" =~ dovecot\.sieve ]] && {
|
||||
sudo sievec /etc/dovecot/global_script/dovecot.sieve
|
||||
sudo chown -R vmail:mail /etc/dovecot/global_script
|
||||
}
|
||||
|
||||
# Handle IPv4 only systems
|
||||
if [ ! -f /proc/net/if_inet6 ];
|
||||
then
|
||||
sudo sed -i 's/^listen.*/listen = \*/' dovecot.conf
|
||||
fi
|
||||
sudo service dovecot restart
|
||||
}
|
||||
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
safe_copy dovecot.conf /etc/dovecot/dovecot.conf
|
||||
safe_copy dovecot-ldap.conf /etc/dovecot/dovecot-ldap.conf
|
||||
case "$1" in
|
||||
pre)
|
||||
do_pre_regen $4
|
||||
;;
|
||||
post)
|
||||
do_post_regen $4
|
||||
;;
|
||||
*)
|
||||
echo "hook called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Setup Sieve
|
||||
sudo mkdir -p /etc/dovecot/global_script
|
||||
sudo chmod -R 770 /etc/dovecot/global_script
|
||||
|
||||
safe_copy dovecot.sieve /etc/dovecot/global_script/dovecot.sieve
|
||||
sudo chmod 660 /etc/dovecot/global_script/dovecot.sieve > /dev/null 2>&1 \
|
||||
|| safe_copy dovecot.sieve /etc/dovecot/global_script/dovecot.sieve
|
||||
sudo sievec /etc/dovecot/global_script/dovecot.sieve
|
||||
sudo chmod 660 /etc/dovecot/global_script/dovecot.svbin
|
||||
sudo chown -R vmail:mail /etc/dovecot/global_script
|
||||
|
||||
sudo service dovecot restart
|
||||
exit 0
|
||||
|
|
92
data/hooks/conf_regen/28-rmilter
Normal file → Executable file
92
data/hooks/conf_regen/28-rmilter
Normal file → Executable file
|
@ -1,43 +1,69 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s rmilter $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s rmilter $1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/rmilter
|
||||
|
||||
install -D -m 644 rmilter.conf \
|
||||
"${pending_dir}/etc/rmilter.conf"
|
||||
install -D -m 644 rmilter.socket \
|
||||
"${pending_dir}/etc/systemd/system/rmilter.socket"
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/rmilter
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
# Copy Rmilter configuration
|
||||
safe_copy rmilter.conf /etc/rmilter.conf
|
||||
# retrieve variables
|
||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
||||
|
||||
# Override socket configuration
|
||||
safe_copy rmilter.socket /etc/systemd/system/rmilter.socket
|
||||
# create DKIM directory
|
||||
sudo mkdir -p /etc/dkim
|
||||
|
||||
# Create DKIM key for each YunoHost domain
|
||||
sudo mkdir -p /etc/dkim
|
||||
domain_list=$(sudo yunohost domain list --output-as plain)
|
||||
# create DKIM key for domains
|
||||
for domain in $domain_list; do
|
||||
domain_key="/etc/dkim/${domain}.mail.key"
|
||||
[ ! -f $domain_key ] && {
|
||||
sudo opendkim-genkey --domain="$domain" \
|
||||
--selector=mail --directory=/etc/dkim
|
||||
sudo mv /etc/dkim/mail.private "$domain_key"
|
||||
sudo mv /etc/dkim/mail.txt "/etc/dkim/${domain}.mail.txt"
|
||||
}
|
||||
done
|
||||
|
||||
for domain in $domain_list; do
|
||||
[ -f /etc/dkim/$domain.mail.key ] \
|
||||
|| (sudo opendkim-genkey --domain=$domain \
|
||||
--selector=mail\
|
||||
--directory=/etc/dkim \
|
||||
&& sudo mv /etc/dkim/mail.private /etc/dkim/$domain.mail.key \
|
||||
&& sudo mv /etc/dkim/mail.txt /etc/dkim/$domain.mail.txt)
|
||||
# fix DKIM keys permissions
|
||||
sudo chown _rmilter /etc/dkim/*.mail.key
|
||||
sudo chmod 400 /etc/dkim/*.mail.key
|
||||
|
||||
sudo chown _rmilter /etc/dkim/$domain.mail.key
|
||||
sudo chmod 400 /etc/dkim/$domain.mail.key
|
||||
done
|
||||
[ -z "$regen_conf_files" ] && exit 0
|
||||
|
||||
# Reload systemd daemon, ensure that the socket is listening and stop
|
||||
# the service. It will be started again by the socket as needed.
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl start rmilter.socket
|
||||
sudo systemctl stop rmilter.service 2>&1 || true
|
||||
# reload systemd daemon
|
||||
[[ "$regen_conf_files" =~ rmilter\.socket ]] && {
|
||||
sudo systemctl -q daemon-reload
|
||||
}
|
||||
|
||||
# ensure that the socket is listening and stop the service - it will be
|
||||
# started again by the socket as needed
|
||||
sudo systemctl -q start rmilter.socket
|
||||
sudo systemctl -q stop rmilter.service 2>&1 || true
|
||||
}
|
||||
|
||||
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
|
||||
|
|
65
data/hooks/conf_regen/31-rspamd
Normal file → Executable file
65
data/hooks/conf_regen/31-rspamd
Normal file → Executable file
|
@ -1,33 +1,50 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s rspamd $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s rspamd $1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/rspamd
|
||||
|
||||
install -D -m 644 metrics.local.conf \
|
||||
"${pending_dir}/etc/rspamd/local.d/metrics.conf"
|
||||
install -D -m 644 rspamd.sieve \
|
||||
"${pending_dir}/etc/dovecot/global_script/rspamd.sieve"
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/rspamd
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
# Create configuration directories
|
||||
sudo mkdir -p /etc/rspamd/local.d /etc/rspamd/override.d
|
||||
[ -z "$regen_conf_files" ] && exit 0
|
||||
|
||||
# Copy specific configuration to rewrite the defaults
|
||||
safe_copy metrics.conf.local /etc/rspamd/local.d/metrics.conf
|
||||
# compile sieve script
|
||||
[[ "$regen_conf_files" =~ rspamd\.sieve ]] && {
|
||||
sudo sievec /etc/dovecot/global_script/rspamd.sieve
|
||||
sudo chown -R vmail:mail /etc/dovecot/global_script
|
||||
sudo systemctl restart dovecot
|
||||
}
|
||||
|
||||
# Install Rspamd sieve script
|
||||
safe_copy rspamd.sieve /etc/dovecot/global_script/rspamd.sieve
|
||||
sudo sievec /etc/dovecot/global_script/rspamd.sieve
|
||||
sudo chmod 660 /etc/dovecot/global_script/rspamd.svbin
|
||||
sudo chown -R vmail:mail /etc/dovecot/global_script
|
||||
# ensure that the socket is listening and stop the service - it will be
|
||||
# started again by the socket as needed
|
||||
sudo systemctl -q start rspamd.socket
|
||||
sudo systemctl -q stop rspamd.service 2>&1 || true
|
||||
}
|
||||
|
||||
# Ensure that the socket is listening and stop the service.
|
||||
sudo systemctl stop rspamd.service 2>&1 || true
|
||||
sudo systemctl start rspamd.socket
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
sudo systemctl restart dovecot
|
||||
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
|
||||
|
|
99
data/hooks/conf_regen/34-mysql
Normal file → Executable file
99
data/hooks/conf_regen/34-mysql
Normal file → Executable file
|
@ -1,35 +1,82 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
force=$1
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s mysql $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s mysql $1 $2
|
||||
fi
|
||||
cd /usr/share/yunohost/templates/mysql
|
||||
|
||||
install -D -m 644 my.cnf "${pending_dir}/etc/mysql/my.cnf"
|
||||
}
|
||||
|
||||
function randpass () {
|
||||
[ "$2" == "0" ] && CHAR="[:alnum:]" || CHAR="[:graph:]"
|
||||
cat /dev/urandom | tr -cd "$CHAR" | head -c ${1:-32}
|
||||
echo
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
if [ ! -f /etc/yunohost/mysql ]; then
|
||||
. /usr/share/yunohost/helpers.d/string
|
||||
|
||||
# ensure that mysql is running
|
||||
service mysql status >/dev/null 2>&1 \
|
||||
|| service mysql start
|
||||
|
||||
# generate and set new root password
|
||||
mysql_password=$(ynh_string_random 10)
|
||||
sudo mysqladmin -s -u root -pyunohost password "$mysql_password" || {
|
||||
if [ $FORCE -eq 1 ]; then
|
||||
. /usr/share/yunohost/helpers.d/package
|
||||
|
||||
echo "It seems that you have already configured MySQL." \
|
||||
"YunoHost needs to have a root access to MySQL to runs its" \
|
||||
"applications, and is going to reset the MySQL root password." \
|
||||
"You can find this new password in /etc/yunohost/mysql." >&2
|
||||
|
||||
# retrieve MySQL package provider
|
||||
ynh_package_is_installed "mariadb-server-10.0" \
|
||||
&& mysql_pkg="mariadb-server-10.0" \
|
||||
|| mysql_pkg="mysql-server-5.5"
|
||||
|
||||
# set new password with debconf
|
||||
sudo debconf-set-selections << EOF
|
||||
$mysql_pkg mysql-server/root_password password $mysql_password
|
||||
$mysql_pkg mysql-server/root_password_again password $mysql_password
|
||||
EOF
|
||||
|
||||
# reconfigure Debian package
|
||||
sudo dpkg-reconfigure -freadline -u "$mysql_pkg" 2>&1
|
||||
else
|
||||
echo "It seems that you have already configured MySQL." \
|
||||
"YunoHost needs to have a root access to MySQL to runs its" \
|
||||
"applications, but the MySQL root password is unknown." \
|
||||
"You must either pass --force to reset the password or" \
|
||||
"put the current one into the file /etc/yunohost/mysql." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# store new root password
|
||||
echo "$mysql_password" | sudo tee /etc/yunohost/mysql
|
||||
sudo chmod 400 /etc/yunohost/mysql
|
||||
fi
|
||||
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service mysql restart
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/mysql
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
if [[ "$(safe_copy my.cnf /etc/mysql/my.cnf | tail -n1)" == "True" ]]; then
|
||||
sudo service mysql restart
|
||||
fi
|
||||
case "$1" in
|
||||
pre)
|
||||
do_pre_regen $4
|
||||
;;
|
||||
post)
|
||||
do_post_regen $4
|
||||
;;
|
||||
*)
|
||||
echo "hook called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -f /etc/yunohost/mysql ]; then
|
||||
[[ $(/bin/ps aux | grep '[m]ysqld') == "0" ]] \
|
||||
&& sudo service mysql start
|
||||
|
||||
mysql_password=$(randpass 10 0)
|
||||
sudo mysqladmin -u root -pyunohost password $mysql_password
|
||||
echo $mysql_password | sudo tee /etc/yunohost/mysql
|
||||
sudo chmod 400 /etc/yunohost/mysql
|
||||
fi
|
||||
exit 0
|
||||
|
|
46
data/hooks/conf_regen/37-avahi-daemon
Normal file → Executable file
46
data/hooks/conf_regen/37-avahi-daemon
Normal file → Executable file
|
@ -1,19 +1,37 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s avahi-daemon $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s avahi-daemon $1 $2
|
||||
fi
|
||||
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"
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/avahi-daemon
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
if [[ "$(safe_copy avahi-daemon.conf /etc/avahi/avahi-daemon.conf | tail -n1)" == "True" ]]; then
|
||||
sudo service avahi-daemon restart
|
||||
fi
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service avahi-daemon restart
|
||||
}
|
||||
|
||||
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
|
||||
|
|
45
data/hooks/conf_regen/40-glances
Normal file → Executable file
45
data/hooks/conf_regen/40-glances
Normal file → Executable file
|
@ -1,19 +1,36 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s glances $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s glances $1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/glances
|
||||
|
||||
install -D -m 644 glances.default "${pending_dir}/etc/default/glances"
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/glances
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
if [[ "$(safe_copy glances.default /etc/default/glances | tail -n1)" == "True" ]]; then
|
||||
sudo service glances restart
|
||||
fi
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service glances restart
|
||||
}
|
||||
|
||||
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
|
||||
|
|
101
data/hooks/conf_regen/43-dnsmasq
Normal file → Executable file
101
data/hooks/conf_regen/43-dnsmasq
Normal file → Executable file
|
@ -1,53 +1,66 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
. /usr/share/yunohost/helpers
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s dnsmasq $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s dnsmasq $1 $2
|
||||
fi
|
||||
# source ip helpers
|
||||
. /usr/share/yunohost/helpers.d/ip
|
||||
|
||||
cd /usr/share/yunohost/templates/dnsmasq
|
||||
|
||||
# create directory for pending conf
|
||||
dnsmasq_dir="${pending_dir}/etc/dnsmasq.d"
|
||||
mkdir -p "$dnsmasq_dir"
|
||||
|
||||
# retrieve variables
|
||||
ipv4=$(curl -s -4 https://ip.yunohost.org 2>/dev/null || true)
|
||||
ynh_validate_ip4 "$ipv4" || ipv4='127.0.0.1'
|
||||
ipv6=$(curl -s -6 http://ip6.yunohost.org 2>/dev/null || true)
|
||||
ynh_validate_ip6 "$ipv6" || ipv6=''
|
||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
||||
|
||||
# add domain conf files
|
||||
for domain in $domain_list; do
|
||||
cat domain.tpl \
|
||||
| sed "s/{{ domain }}/${domain}/g" \
|
||||
| sed "s/{{ ip }}/${ipv4}/g" \
|
||||
> "${dnsmasq_dir}/${domain}"
|
||||
[[ -n $ipv6 ]] \
|
||||
&& echo "address=/${domain}/${ipv6}" >> "${dnsmasq_dir}/${domain}"
|
||||
done
|
||||
|
||||
# remove old domain conf files
|
||||
conf_files=$(ls -1 /etc/dnsmasq.d \
|
||||
| awk '/^[^\.]+\.[^\.]+.*$/ { print $1 }')
|
||||
for domain in $conf_files; do
|
||||
[[ $domain_list =~ $domain ]] \
|
||||
|| touch "${dnsmasq_dir}/${domain}"
|
||||
done
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/dnsmasq
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
# Get IPv4 address
|
||||
ip=$(curl -s -4 https://ip.yunohost.org 2>/dev/null || true)
|
||||
ynh_validate_ip4 $ip || ip='0.0.0.0'
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service dnsmasq restart
|
||||
}
|
||||
|
||||
# Get IPv6 IP address
|
||||
ipv6=$(curl -s -6 http://ip6.yunohost.org 2>/dev/null || true)
|
||||
ynh_validate_ip6 $ipv6 || ipv6=''
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
sudo mkdir -p /etc/dnsmasq.d
|
||||
case "$1" in
|
||||
pre)
|
||||
do_pre_regen $4
|
||||
;;
|
||||
post)
|
||||
do_post_regen $4
|
||||
;;
|
||||
*)
|
||||
echo "hook called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
domain_list=$(sudo yunohost domain list --output-as plain)
|
||||
|
||||
# Copy a configuration file for each YunoHost domain
|
||||
for domain in $domain_list; do
|
||||
cat domain.sed \
|
||||
| sed "s/{{ domain }}/$domain/g" \
|
||||
| sed "s/{{ ip }}/$ip/g" \
|
||||
| sudo tee $domain
|
||||
|
||||
if [[ "$ipv6" != "" ]]; then
|
||||
echo "address=/$domain/$ipv6" | sudo tee -a $domain
|
||||
fi
|
||||
|
||||
safe_copy $domain /etc/dnsmasq.d/$domain
|
||||
done
|
||||
|
||||
# Remove old domains files
|
||||
for file in /etc/dnsmasq.d/*.*; do
|
||||
domain=$(echo $file | sed 's|/etc/dnsmasq.d/||')
|
||||
[[ $domain_list =~ $domain ]] \
|
||||
|| sudo yunohost service saferemove -s dnsmasq $file
|
||||
done
|
||||
|
||||
sudo service dnsmasq reload \
|
||||
|| sudo service dnsmasq restart
|
||||
exit 0
|
||||
|
|
45
data/hooks/conf_regen/46-nsswitch
Normal file → Executable file
45
data/hooks/conf_regen/46-nsswitch
Normal file → Executable file
|
@ -1,19 +1,36 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s nsswitch $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s nsswitch $1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/nsswitch
|
||||
|
||||
install -D -m 644 nsswitch.conf "${pending_dir}/etc/nsswitch.conf"
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/nsswitch
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
if [[ "$(safe_copy nsswitch.conf /etc/nsswitch.conf | tail -n1)" == "True" ]]; then
|
||||
sudo service nscd restart
|
||||
fi
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service nscd restart
|
||||
}
|
||||
|
||||
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
|
||||
|
|
54
data/hooks/conf_regen/52-fail2ban
Normal file → Executable file
54
data/hooks/conf_regen/52-fail2ban
Normal file → Executable file
|
@ -1,28 +1,40 @@
|
|||
set -e
|
||||
#!/bin/bash
|
||||
|
||||
force=$1
|
||||
set -e
|
||||
|
||||
function safe_copy () {
|
||||
if [[ "$force" == "True" ]]; then
|
||||
sudo yunohost service safecopy \
|
||||
-s fail2ban $1 $2 --force
|
||||
else
|
||||
sudo yunohost service safecopy \
|
||||
-s fail2ban $1 $2
|
||||
fi
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
cd /usr/share/yunohost/templates/fail2ban
|
||||
|
||||
fail2ban_dir="${pending_dir}/etc/fail2ban"
|
||||
mkdir -p "${fail2ban_dir}/filter.d"
|
||||
|
||||
cp yunohost.conf "${fail2ban_dir}/filter.d/yunohost.conf"
|
||||
cp jail.conf "${fail2ban_dir}/jail.conf"
|
||||
}
|
||||
|
||||
cd /usr/share/yunohost/templates/fail2ban
|
||||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
sudo mkdir -p /etc/fail2ban/filter.d
|
||||
safe_copy yunohost.conf /etc/fail2ban/filter.d/yunohost.conf
|
||||
[[ -z "$regen_conf_files" ]] \
|
||||
|| sudo service fail2ban restart
|
||||
}
|
||||
|
||||
# Compatibility: change from HDB to MDB on Jessie
|
||||
version=$(sed 's/\..*//' /etc/debian_version)
|
||||
[[ "$version" == '8' ]] \
|
||||
&& sudo cp jail-jessie.conf jail.conf \
|
||||
|| sudo cp jail-wheezy.conf jail.conf
|
||||
FORCE=${2:-0}
|
||||
DRY_RUN=${3:-0}
|
||||
|
||||
if [[ $(safe_copy jail.conf /etc/fail2ban/jail.conf | tail -n1) == "True" ]]; then
|
||||
sudo service fail2ban restart
|
||||
fi
|
||||
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
|
||||
|
|
|
@ -1,6 +1,42 @@
|
|||
backup_dir="$1/conf/ynh/mysql"
|
||||
|
||||
sudo service mysql restart
|
||||
sudo cp -a $backup_dir/mysql /etc/yunohost/mysql
|
||||
mysqlpwd=$(sudo cat /etc/yunohost/mysql)
|
||||
sudo mysqladmin flush-privileges -p"$mysqlpwd"
|
||||
# ensure that mysql is running
|
||||
service mysql status >/dev/null 2>&1 \
|
||||
|| service mysql start
|
||||
|
||||
# retrieve current and new password
|
||||
[ -f /etc/yunohost/mysql ] \
|
||||
&& curr_pwd=$(sudo cat /etc/yunohost/mysql) \
|
||||
|| curr_pwd="yunohost"
|
||||
new_pwd=$(sudo cat "${backup_dir}/root_pwd" || sudo cat "${backup_dir}/mysql")
|
||||
|
||||
# attempt to change it
|
||||
sudo mysqladmin -s -u root -p"$curr_pwd" password "$new_pwd" || {
|
||||
. /usr/share/yunohost/helpers.d/package
|
||||
|
||||
echo "It seems that you have already configured MySQL." \
|
||||
"YunoHost needs to have a root access to MySQL to runs its" \
|
||||
"applications, and is going to reset the MySQL root password." \
|
||||
"You can find this new password in /etc/yunohost/mysql." >&2
|
||||
|
||||
# retrieve MySQL package provider
|
||||
ynh_package_is_installed "mariadb-server-10.0" \
|
||||
&& mysql_pkg="mariadb-server-10.0" \
|
||||
|| mysql_pkg="mysql-server-5.5"
|
||||
|
||||
# set new password with debconf
|
||||
sudo debconf-set-selections << EOF
|
||||
$mysql_pkg mysql-server/root_password password $new_pwd
|
||||
$mysql_pkg mysql-server/root_password_again password $new_pwd
|
||||
EOF
|
||||
|
||||
# reconfigure Debian package
|
||||
sudo dpkg-reconfigure -freadline -u "$mysql_pkg" 2>&1
|
||||
}
|
||||
|
||||
# store new root password
|
||||
echo "$new_pwd" | sudo tee /etc/yunohost/mysql
|
||||
sudo chmod 400 /etc/yunohost/mysql
|
||||
|
||||
# reload the grant tables
|
||||
sudo mysqladmin -s -u root -p"$new_pwd" reload
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
backup_dir="$1/conf/ynh"
|
||||
|
||||
sudo cp -a "${backup_dir}/current_host" /etc/yunohost/current_host
|
||||
|
|
|
@ -1,346 +0,0 @@
|
|||
# Fail2Ban configuration file.
|
||||
#
|
||||
# This file was composed for Debian systems from the original one
|
||||
# provided now under /usr/share/doc/fail2ban/examples/jail.conf
|
||||
# for additional examples.
|
||||
#
|
||||
# To avoid merges during upgrades DO NOT MODIFY THIS FILE
|
||||
# and rather provide your changes in /etc/fail2ban/jail.local
|
||||
#
|
||||
# Author: Yaroslav O. Halchenko <debian@onerussian.com>
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
# The DEFAULT allows a global definition of the options. They can be overridden
|
||||
# in each jail afterwards.
|
||||
|
||||
[DEFAULT]
|
||||
|
||||
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
|
||||
ignoreip = 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
|
||||
bantime = 600
|
||||
maxretry = 3
|
||||
|
||||
# "backend" specifies the backend used to get files modification. Available
|
||||
# options are "gamin", "polling" and "auto".
|
||||
# yoh: For some reason Debian shipped python-gamin didn't work as expected
|
||||
# This issue left ToDo, so polling is default backend for now
|
||||
backend = auto
|
||||
|
||||
#
|
||||
# Destination email address used solely for the interpolations in
|
||||
# jail.{conf,local} configuration files.
|
||||
destemail = root@localhost
|
||||
|
||||
#
|
||||
# ACTIONS
|
||||
#
|
||||
|
||||
# Default banning action (e.g. iptables, iptables-new,
|
||||
# iptables-multiport, shorewall, etc) It is used to define
|
||||
# action_* variables. Can be overridden globally or per
|
||||
# section within jail.local file
|
||||
banaction = iptables-multiport
|
||||
|
||||
# email action. Since 0.8.1 upstream fail2ban uses sendmail
|
||||
# MTA for the mailing. Change mta configuration parameter to mail
|
||||
# if you want to revert to conventional 'mail'.
|
||||
mta = sendmail
|
||||
|
||||
# Default protocol
|
||||
protocol = tcp
|
||||
|
||||
# Specify chain where jumps would need to be added in iptables-* actions
|
||||
chain = INPUT
|
||||
|
||||
#
|
||||
# Action shortcuts. To be used to define action parameter
|
||||
|
||||
# The simplest action to take: ban only
|
||||
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
# ban & send an e-mail with whois report to the destemail.
|
||||
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
%(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
# ban & send an e-mail with whois report and relevant log lines
|
||||
# to the destemail.
|
||||
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
%(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]
|
||||
|
||||
# Choose default action. To change, just override value of 'action' with the
|
||||
# interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local
|
||||
# globally (section [DEFAULT]) or per specific section
|
||||
action = %(action_)s
|
||||
|
||||
#
|
||||
# JAILS
|
||||
#
|
||||
|
||||
# Next jails corresponds to the standard configuration in Fail2ban 0.6 which
|
||||
# was shipped in Debian. Enable any defined here jail by including
|
||||
#
|
||||
# [SECTION_NAME]
|
||||
# enabled = true
|
||||
|
||||
#
|
||||
# in /etc/fail2ban/jail.local.
|
||||
#
|
||||
# Optionally you may override any other parameter (e.g. banaction,
|
||||
# action, port, logpath, etc) in that section within jail.local
|
||||
|
||||
[ssh]
|
||||
|
||||
enabled = true
|
||||
port = ssh
|
||||
filter = sshd
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 6
|
||||
|
||||
[dropbear]
|
||||
|
||||
enabled = false
|
||||
port = ssh
|
||||
filter = sshd
|
||||
logpath = /var/log/dropbear
|
||||
maxretry = 6
|
||||
|
||||
# Generic filter for pam. Has to be used with action which bans all ports
|
||||
# such as iptables-allports, shorewall
|
||||
[pam-generic]
|
||||
|
||||
enabled = false
|
||||
# pam-generic filter can be customized to monitor specific subset of 'tty's
|
||||
filter = pam-generic
|
||||
# port actually must be irrelevant but lets leave it all for some possible uses
|
||||
port = all
|
||||
banaction = iptables-allports
|
||||
port = anyport
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 6
|
||||
|
||||
[xinetd-fail]
|
||||
|
||||
enabled = false
|
||||
filter = xinetd-fail
|
||||
port = all
|
||||
banaction = iptables-multiport-log
|
||||
logpath = /var/log/daemon.log
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[ssh-ddos]
|
||||
|
||||
enabled = false
|
||||
port = ssh
|
||||
filter = sshd-ddos
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 6
|
||||
|
||||
#
|
||||
# HTTP servers
|
||||
#
|
||||
|
||||
[apache]
|
||||
|
||||
enabled = false
|
||||
port = http,https
|
||||
filter = apache-auth
|
||||
logpath = /var/log/apache*/*error.log
|
||||
maxretry = 6
|
||||
|
||||
# default action is now multiport, so apache-multiport jail was left
|
||||
# for compatibility with previous (<0.7.6-2) releases
|
||||
[apache-multiport]
|
||||
|
||||
enabled = false
|
||||
port = http,https
|
||||
filter = apache-auth
|
||||
logpath = /var/log/apache*/*error.log
|
||||
maxretry = 6
|
||||
|
||||
[apache-noscript]
|
||||
|
||||
enabled = false
|
||||
port = http,https
|
||||
filter = apache-noscript
|
||||
logpath = /var/log/apache*/*error.log
|
||||
maxretry = 6
|
||||
|
||||
[apache-overflows]
|
||||
|
||||
enabled = false
|
||||
port = http,https
|
||||
filter = apache-overflows
|
||||
logpath = /var/log/apache*/*error.log
|
||||
maxretry = 2
|
||||
|
||||
#
|
||||
# FTP servers
|
||||
#
|
||||
|
||||
[vsftpd]
|
||||
|
||||
enabled = false
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
filter = vsftpd
|
||||
logpath = /var/log/vsftpd.log
|
||||
# or overwrite it in jails.local to be
|
||||
# logpath = /var/log/auth.log
|
||||
# if you want to rely on PAM failed login attempts
|
||||
# vsftpd's failregex should match both of those formats
|
||||
maxretry = 6
|
||||
|
||||
|
||||
[proftpd]
|
||||
|
||||
enabled = false
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
filter = proftpd
|
||||
logpath = /var/log/proftpd/proftpd.log
|
||||
maxretry = 6
|
||||
|
||||
|
||||
[pure-ftpd]
|
||||
|
||||
enabled = false
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
filter = pure-ftpd
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 6
|
||||
|
||||
|
||||
[wuftpd]
|
||||
|
||||
enabled = false
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
filter = wuftpd
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 6
|
||||
|
||||
|
||||
#
|
||||
# Mail servers
|
||||
#
|
||||
|
||||
[postfix]
|
||||
|
||||
enabled = true
|
||||
port = smtp,ssmtp
|
||||
filter = postfix
|
||||
logpath = /var/log/mail.log
|
||||
|
||||
[couriersmtp]
|
||||
|
||||
enabled = false
|
||||
port = smtp,ssmtp
|
||||
filter = couriersmtp
|
||||
logpath = /var/log/mail.log
|
||||
|
||||
|
||||
#
|
||||
# Mail servers authenticators: might be used for smtp,ftp,imap servers, so
|
||||
# all relevant ports get banned
|
||||
#
|
||||
|
||||
[courierauth]
|
||||
|
||||
enabled = false
|
||||
port = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
|
||||
filter = courierlogin
|
||||
logpath = /var/log/mail.log
|
||||
|
||||
|
||||
[sasl]
|
||||
|
||||
enabled = true
|
||||
port = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
|
||||
filter = sasl
|
||||
# You might consider monitoring /var/log/mail.warn instead if you are
|
||||
# running postfix since it would provide the same log lines at the
|
||||
# "warn" level but overall at the smaller filesize.
|
||||
logpath = /var/log/mail.log
|
||||
|
||||
[dovecot]
|
||||
|
||||
enabled = true
|
||||
port = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
|
||||
filter = dovecot
|
||||
logpath = /var/log/mail.log
|
||||
|
||||
|
||||
# DNS Servers
|
||||
|
||||
|
||||
# These jails block attacks against named (bind9). By default, logging is off
|
||||
# with bind9 installation. You will need something like this:
|
||||
#
|
||||
# logging {
|
||||
# channel security_file {
|
||||
# file "/var/log/named/security.log" versions 3 size 30m;
|
||||
# severity dynamic;
|
||||
# print-time yes;
|
||||
# };
|
||||
# category security {
|
||||
# security_file;
|
||||
# };
|
||||
# };
|
||||
#
|
||||
# in your named.conf to provide proper logging
|
||||
|
||||
# !!! WARNING !!!
|
||||
# Since UDP is connection-less protocol, spoofing of IP and imitation
|
||||
# of illegal actions is way too simple. Thus enabling of this filter
|
||||
# might provide an easy way for implementing a DoS against a chosen
|
||||
# victim. See
|
||||
# http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html
|
||||
# Please DO NOT USE this jail unless you know what you are doing.
|
||||
#[named-refused-udp]
|
||||
#
|
||||
#enabled = false
|
||||
#port = domain,953
|
||||
#protocol = udp
|
||||
#filter = named-refused
|
||||
#logpath = /var/log/named/security.log
|
||||
|
||||
[named-refused-tcp]
|
||||
|
||||
enabled = false
|
||||
port = domain,953
|
||||
protocol = tcp
|
||||
filter = named-refused
|
||||
logpath = /var/log/named/security.log
|
||||
|
||||
[nginx]
|
||||
|
||||
enabled = true
|
||||
port = http,https
|
||||
filter = apache-auth
|
||||
logpath = /var/log/nginx*/*error.log
|
||||
maxretry = 6
|
||||
|
||||
[nginx-noscript]
|
||||
|
||||
enabled = false
|
||||
port = http,https
|
||||
filter = apache-noscript
|
||||
logpath = /var/log/nginx*/*error.log
|
||||
maxretry = 6
|
||||
|
||||
[nginx-overflows]
|
||||
|
||||
enabled = false
|
||||
port = http,https
|
||||
filter = apache-overflows
|
||||
logpath = /var/log/nginx*/*error.log
|
||||
maxretry = 4
|
||||
|
||||
[yunohost]
|
||||
|
||||
enabled = true
|
||||
port = http,https
|
||||
protocol = tcp
|
||||
filter = yunohost
|
||||
logpath = /var/log/nginx/*.log
|
||||
maxretry = 6
|
|
@ -15,8 +15,13 @@ postfix:
|
|||
log: [/var/log/mail.log,/var/log/mail.err]
|
||||
rmilter:
|
||||
status: systemctl status rmilter.socket
|
||||
log: /var/log/mail.log
|
||||
rspamd:
|
||||
status: systemctl status rspamd.socket
|
||||
log: /var/log/mail.log
|
||||
redis-server:
|
||||
status: service
|
||||
log: /var/log/redis/redis-server.log
|
||||
mysql:
|
||||
status: service
|
||||
log: [/var/log/mysql.log,/var/log/mysql.err]
|
||||
|
@ -39,9 +44,6 @@ yunohost-api:
|
|||
log: /var/log/yunohost/yunohost-api.log
|
||||
yunohost-firewall:
|
||||
status: service
|
||||
postgrey:
|
||||
status: service
|
||||
log: /var/log/mail.log
|
||||
nslcd:
|
||||
status: service
|
||||
log: /var/log/syslog
|
||||
|
@ -49,3 +51,6 @@ nsswitch:
|
|||
status: service
|
||||
udisks2:
|
||||
status: service
|
||||
amavis: null
|
||||
postgrey: null
|
||||
spamassassin: null
|
||||
|
|
39
debian/changelog
vendored
39
debian/changelog
vendored
|
@ -1,3 +1,42 @@
|
|||
yunohost (2.3.12.1) testing; urgency=low
|
||||
|
||||
* [deb] Rely on dh_installinit to restart yunohost-firewall after upgrade
|
||||
* [deb] Add Install section to yunohost-firewall.service
|
||||
|
||||
-- Jérôme Lebleu <jerome@yunohost.org> Sat, 09 Apr 2016 17:22:40 +0200
|
||||
|
||||
yunohost (2.3.12) testing; urgency=low
|
||||
|
||||
[ Jérôme Lebleu ]
|
||||
* [enh] Use new rspamd configuration system to override metrics
|
||||
* [enh] Allow to set script execution directory in hook_exec
|
||||
* [enh] Add a ynh_user_list helper
|
||||
* [enh] Call app remove script if installation fails
|
||||
* [fix] Move imports at the top in yunohost and yunohost-api
|
||||
* [fix] Use rspamd local.d folder to allow users to override the defaults
|
||||
* [fix] Execute backup/restore app scripts from the backup dir (bugfix #139)
|
||||
* [fix] Regenerate SSOwat conf after apps restoration
|
||||
* [fix] Move imports at the top in backup.py
|
||||
* [fix] Check if the package is actually installed in equivs helper
|
||||
* [fix] Improve control file management in equivs helper
|
||||
* [fix] Remove ending comma in backup.py
|
||||
* [fix] Call yunohost commands with --quiet in setting helpers
|
||||
* [fix] Check for tty in root_handlers before remove it in bin/yunohost
|
||||
* [fix] Use dyndns.yunohost.org instead of dynhost.yunohost.org
|
||||
* [fix] Set found private key and don't validate it in dyndns_update
|
||||
* [fix] Update first registered domain with DynDNS instead of current_host
|
||||
* [i18n] Rename app_requirements_failed err named variable
|
||||
* [i18n] Update translations from Weblate
|
||||
|
||||
[ opi ]
|
||||
* [enh] Better message during service regenconf.
|
||||
* [enh] Display hook path on error message.
|
||||
* [enh] Use named arguments when calling m18n in service.py
|
||||
* [enh] Use named arguments with m18n.
|
||||
* [enh] Use named arguments for user_unknown string.
|
||||
|
||||
-- Jérôme Lebleu <jerome@yunohost.org> Sat, 09 Apr 2016 12:13:10 +0200
|
||||
|
||||
moulinette-yunohost (2.2.4) stable; urgency=low
|
||||
|
||||
[ Jérôme Lebleu ]
|
||||
|
|
4
debian/control
vendored
4
debian/control
vendored
|
@ -10,7 +10,7 @@ Homepage: https://yunohost.org/
|
|||
Package: yunohost
|
||||
Architecture: all
|
||||
Depends: ${python:Depends}, ${misc:Depends}
|
||||
, moulinette (>= 2.3.4)
|
||||
, moulinette (>= 2.3.5.1)
|
||||
, python-psutil, python-requests, python-dnspython
|
||||
, python-apt, python-miniupnpc
|
||||
, glances
|
||||
|
@ -27,7 +27,7 @@ Depends: ${python:Depends}, ${misc:Depends}
|
|||
, rspamd (>= 1.2.0), rmilter (>=1.7.0), redis-server, opendkim-tools
|
||||
Recommends: yunohost-admin
|
||||
, openssh-server, ntp, inetutils-ping | iputils-ping
|
||||
, bash-completion, rsyslog
|
||||
, bash-completion, rsyslog, etckeeper
|
||||
, php5-gd, php5-curl, php-gettext, php5-mcrypt
|
||||
, python-pip
|
||||
, unattended-upgrades
|
||||
|
|
41
debian/postinst
vendored
41
debian/postinst
vendored
|
@ -6,13 +6,13 @@ do_configure() {
|
|||
rm -rf /var/cache/moulinette/*
|
||||
|
||||
if [ ! -f /etc/yunohost/installed ]; then
|
||||
bash /usr/share/yunohost/hooks/conf_regen/01-yunohost True
|
||||
bash /usr/share/yunohost/hooks/conf_regen/02-ssl True
|
||||
bash /usr/share/yunohost/hooks/conf_regen/06-slapd True
|
||||
bash /usr/share/yunohost/hooks/conf_regen/15-nginx True
|
||||
bash /usr/share/yunohost/hooks/conf_regen/01-yunohost init
|
||||
bash /usr/share/yunohost/hooks/conf_regen/02-ssl init
|
||||
bash /usr/share/yunohost/hooks/conf_regen/06-slapd init
|
||||
bash /usr/share/yunohost/hooks/conf_regen/15-nginx init
|
||||
else
|
||||
echo "Regenerating configuration, this might take a while..."
|
||||
yunohost service regenconf
|
||||
yunohost service regen-conf --output-as none
|
||||
|
||||
# restart yunohost-firewall if it's running
|
||||
service yunohost-firewall status >/dev/null \
|
||||
|
@ -28,23 +28,18 @@ do_configure() {
|
|||
restart_yunohost_firewall() {
|
||||
echo "Restarting YunoHost firewall..."
|
||||
|
||||
if [ -x /etc/init.d/yunohost-firewall ]; then
|
||||
update-rc.d yunohost-firewall defaults >/dev/null || true
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
else
|
||||
invoke-rc.d yunohost-firewall start >/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
deb-systemd-helper unmask yunohost-firewall.service >/dev/null || true
|
||||
if deb-systemd-helper --quiet was-enabled yunohost-firewall.service; then
|
||||
deb-systemd-helper enable yunohost-firewall.service >/dev/null || true
|
||||
else
|
||||
deb-systemd-helper update-state yunohost-firewall.service >/dev/null || true
|
||||
fi
|
||||
deb-systemd-helper update-state yunohost-firewall.service >/dev/null || true
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
deb-systemd-invoke try-restart yunohost-firewall.service >/dev/null || true
|
||||
|
||||
if [ -x /etc/init.d/yunohost-firewall ]; then
|
||||
update-rc.d yunohost-firewall enable >/dev/null
|
||||
if [ -n "$2" ]; then
|
||||
invoke-rc.d yunohost-firewall restart >/dev/null || exit $?
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -71,16 +66,6 @@ case "$1" in
|
|||
;;
|
||||
esac
|
||||
|
||||
# Enable and start yunohost-api sysv service
|
||||
if [ -x /etc/init.d/yunohost-api ]; then
|
||||
update-rc.d yunohost-api defaults >/dev/null
|
||||
if [ -d /run/systemd/system ]; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
else
|
||||
invoke-rc.d yunohost-api start || exit $?
|
||||
fi
|
||||
fi
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
|
|
1
debian/postrm
vendored
1
debian/postrm
vendored
|
@ -3,7 +3,6 @@
|
|||
set -e
|
||||
|
||||
if [ "$1" = "purge" ]; then
|
||||
update-rc.d yunohost-api remove >/dev/null
|
||||
update-rc.d yunohost-firewall remove >/dev/null
|
||||
fi
|
||||
|
||||
|
|
1
debian/prerm
vendored
1
debian/prerm
vendored
|
@ -3,7 +3,6 @@
|
|||
set -e
|
||||
|
||||
if [ -x /etc/init.d/yunohost-api ] && ! [ -d /run/systemd/system ]; then
|
||||
invoke-rc.d yunohost-api stop || exit $?
|
||||
invoke-rc.d yunohost-firewall stop || true
|
||||
fi
|
||||
|
||||
|
|
12
debian/rules
vendored
12
debian/rules
vendored
|
@ -8,12 +8,14 @@
|
|||
dh ${@} --with=python2,systemd
|
||||
|
||||
override_dh_installinit:
|
||||
dh_installinit -pyunohost --name=yunohost-api --noscripts
|
||||
dh_installinit -pyunohost --name=yunohost-api --restart-after-upgrade
|
||||
dh_installinit -pyunohost --name=yunohost-firewall --noscripts
|
||||
|
||||
override_dh_systemd_enable:
|
||||
dh_systemd_enable --name=yunohost-api
|
||||
dh_systemd_enable --name=yunohost-firewall --no-enable
|
||||
dh_systemd_enable --name=yunohost-api \
|
||||
yunohost-api.service
|
||||
dh_systemd_enable --name=yunohost-firewall --no-enable \
|
||||
yunohost-firewall.service
|
||||
|
||||
override_dh_systemd_start:
|
||||
dh_systemd_start --restart-after-upgrade yunohost-api.service
|
||||
#override_dh_systemd_start:
|
||||
# dh_systemd_start --restart-after-upgrade yunohost-api.service
|
||||
|
|
3
debian/yunohost-firewall.service
vendored
3
debian/yunohost-firewall.service
vendored
|
@ -9,3 +9,6 @@ ExecStart=/usr/bin/yunohost firewall reload
|
|||
ExecReload=/usr/bin/yunohost firewall reload
|
||||
ExecStop=/usr/bin/yunohost firewall stop
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
422
locales/de.json
422
locales/de.json
|
@ -1,213 +1,213 @@
|
|||
{
|
||||
"action_invalid": "Ungültige Aktion '{:s}'",
|
||||
"admin_password": "Verwaltungspasswort",
|
||||
"admin_password_change_failed": "Passwort kann nicht geändert werden",
|
||||
"admin_password_changed": "Verwaltungspasswort wurde erfolgreich geändert",
|
||||
"app_already_installed": "{:s} ist schon installiert",
|
||||
"app_argument_choice_invalid": "Invalide Auswahl für Argument '{name:s}'. Muss einer der folgenden Werte sein {choices:s}",
|
||||
"app_argument_invalid": "Das Argument '{name:s}' hat einen falschen Wert: {error:s}",
|
||||
"app_argument_required": "Argument '{name:s}' wird benötigt",
|
||||
"app_extraction_failed": "Installationsdateien konnten nicht entpackt werden",
|
||||
"app_id_invalid": "Falsche App ID",
|
||||
"app_install_files_invalid": "Ungültige Installationsdateien",
|
||||
"app_location_already_used": "Eine andere App ist bereits an diesem Ort installiert",
|
||||
"app_location_install_failed": "Die App kann an diesem Ort nicht installiert werden",
|
||||
"app_manifest_invalid": "Ungültiges App Manifest",
|
||||
"app_no_upgrade": "Keine Aktualisierungen für Apps verfügbar",
|
||||
"app_not_installed": "{:s} ist nicht intalliert",
|
||||
"app_recent_version_required": "Für {:s} benötigt eine aktuellere Version von moulinette",
|
||||
"app_removed": "{:s} wurde erfolgreich entfernt",
|
||||
"app_sources_fetch_failed": "Quelldateien konnten nicht abgerufen werden",
|
||||
"app_unknown": "Unbekannte App",
|
||||
"app_upgrade_failed": "Apps konnten nicht aktualisiert werden",
|
||||
"app_upgraded": "{:s} wurde erfolgreich aktualisiert",
|
||||
"appslist_fetched": "Liste der Apps wurde erfolgreich heruntergelanden",
|
||||
"appslist_removed": "Appliste erfolgreich entfernt",
|
||||
"appslist_retrieve_error": "Entfernte App Liste kann nicht gezogen werden",
|
||||
"appslist_unknown": "Unbekannte App Liste",
|
||||
"ask_current_admin_password": "Derzeitiges Verwaltungspasswort",
|
||||
"ask_email": "E-Mail Adresse",
|
||||
"ask_firstname": "Vorname",
|
||||
"ask_lastname": "Nachname",
|
||||
"ask_list_to_remove": "Liste enternen",
|
||||
"ask_main_domain": "Hauptdomain",
|
||||
"ask_new_admin_password": "Neues Verwaltungskennwort",
|
||||
"ask_password": "Passwort",
|
||||
"backup_action_required": "Du musst etwas zum Speichern auswählen",
|
||||
"backup_app_failed": "Konnte keine Sicherung für '{app:s}' erstellen",
|
||||
"backup_archive_app_not_found": "App '{app:s}' konnte in keiner Datensicherung gefunden werden",
|
||||
"backup_archive_hook_not_exec": "Hook '{hook:s}' konnte für diese Datensicherung nicht ausgeführt werden",
|
||||
"backup_archive_name_exists": "Datensicherung mit dem selben Namen existiert bereits",
|
||||
"backup_archive_name_unknown": "Unbekanntes lokale Datensicherung mit Namen '{name:s}' gefunden",
|
||||
"backup_archive_open_failed": "Kann Sicherungsarchiv nicht öfnen",
|
||||
"backup_cleaning_failed": "Verzeichnis von temporäre Sicherungsdaten konnte nicht geleert werden",
|
||||
"backup_complete": "Datensicherung komplett",
|
||||
"backup_creating_archive": "Datensicherung wird erstellt...",
|
||||
"backup_delete_error": "Pfad '{path:s}' konnte nicht gelöscht werden",
|
||||
"backup_deleted": "Datensicherung erfolgreich gelöscht",
|
||||
"backup_extracting_archive": "Entpacke Sicherungsarchiv...",
|
||||
"backup_hook_unknown": "Datensicherungshook '{hook:s}' unbekannt",
|
||||
"backup_invalid_archive": "Ungültige Datensicherung",
|
||||
"backup_nothings_done": "Es gibt keine Änderungen zur Speicherung",
|
||||
"backup_output_directory_forbidden": "Verbotenes Ausgabeverzeichnis",
|
||||
"backup_output_directory_not_empty": "Ausgabeordner ist nicht leer",
|
||||
"backup_output_directory_required": "Für die Datensicherung muss ein Zielverzeichnis angegeben werden",
|
||||
"backup_running_app_script": "Datensicherung für App '{app:s}' wurd durchgeführt...",
|
||||
"backup_running_hooks": "Datensicherunghook wird ausgeführt...",
|
||||
"custom_app_url_required": "Es muss eine URL angegeben um deine benutzerdefinierte App {:s} zu aktualisieren",
|
||||
"custom_appslist_name_required": "Du musst einen Namen für deine benutzerdefinierte Appliste angeben",
|
||||
"dnsmasq_isnt_installed": "dnsmasq scheint nicht installiert zu sein. Bitte führe 'apt-get remove bind9 && apt-get install dnsmasq' aus",
|
||||
"domain_cert_gen_failed": "Zertifikat konnte nicht erzeugt werden",
|
||||
"domain_created": "Domain erfolgreich erzeugt",
|
||||
"domain_creation_failed": "Konnte Domain nicht erzeugen",
|
||||
"domain_deleted": "Domain erfolgreich gelöscht",
|
||||
"domain_deletion_failed": "Konnte Domain nicht löschen",
|
||||
"domain_dyndns_already_subscribed": "Du hast dich schon für einen DynDNS-Domain angemeldet",
|
||||
"domain_dyndns_invalid": "Domain nicht mittels DynDNS nutzbar",
|
||||
"domain_dyndns_root_unknown": "Unbekannte DynDNS Hauptdomain",
|
||||
"domain_exists": "Die Domain existiert bereits",
|
||||
"domain_uninstall_app_first": "Mindestens eine App ist noch für diese Domain installiert. Bitte zuerst die App deinstallieren und erst dann die Domain löschen..",
|
||||
"domain_unknown": "Unbekannte Domain",
|
||||
"domain_zone_exists": "DNS Zonen Datei existiert bereits",
|
||||
"domain_zone_not_found": "DNS Zonen Datei kann nicht für Domäne {:s} gefunden werden",
|
||||
"done": "Erledigt.",
|
||||
"downloading": "Wird heruntergeladen...",
|
||||
"dyndns_cron_installed": "DynDNS Cronjob erfolgreich installiert",
|
||||
"dyndns_cron_remove_failed": "DynDNS Cronjob konnte nicht entfernt werden",
|
||||
"dyndns_cron_removed": "DynDNS Cronjob wurde erfolgreich gelöscht",
|
||||
"dyndns_ip_update_failed": "IP Adresse konnte nicht für DynDNS aktualisiert werden",
|
||||
"dyndns_ip_updated": "IP Adresse wurde erfolgreich für DynDNS aktualisiert",
|
||||
"dyndns_key_generating": "DNS Schlüssel wird generiert, das könnte eine Weile dauern...",
|
||||
"dyndns_registered": "DynDNS Domain erfolgreich registriert",
|
||||
"dyndns_registration_failed": "DynDNS Domain {:s} konnte nicht registriert werden",
|
||||
"dyndns_unavailable": "DynDNS Subdomain ist nicht verfügbar",
|
||||
"executing_command": "Führe Kommendo '{command:s}' aus...",
|
||||
"executing_script": "Skript '{script:s}' wird ausgeührt...",
|
||||
"extracting": "Wird entpackt...",
|
||||
"field_invalid": "Feld '{:s}' ist unbekannt",
|
||||
"firewall_reload_failed": "Firewall konnte nicht neu geladen werden",
|
||||
"firewall_reloaded": "Firewall erfolgreich neu geladen",
|
||||
"firewall_rules_cmd_failed": "Einzelne Firewallregeln konnten nicht übernommen werden. Mehr Informationen sind im Log zu finden.",
|
||||
"format_datetime_short": "%m/%d/%Y %I:%M %p",
|
||||
"hook_argument_missing": "Fehlend Argument '{:s}'",
|
||||
"hook_choice_invalid": "ungültige Wahl '{:s}'",
|
||||
"hook_exec_failed": "Skriptausführung fehlgeschlagen",
|
||||
"hook_exec_not_terminated": "Skriptausführung noch nicht beendet",
|
||||
"hook_list_by_invalid": "Ungültiger Wert zur Anzeige von Hooks",
|
||||
"hook_name_unknown": "Hook '{:s}' ist nicht bekannt",
|
||||
"installation_complete": "Installation vollständig",
|
||||
"installation_failed": "Installation fehlgeschlagen",
|
||||
"ip6tables_unavailable": "ip6tables kann nicht verwendet werden. Du befindest dich entweder in einem Container, oder es wird nicht vom Kernel unterstützt.",
|
||||
"iptables_unavailable": "iptables kann nicht verwendet werden. Du befindest dich entweder in einem Container, oder es wird nicht vom Kernel unterstützt.",
|
||||
"ldap_initialized": "LDAP erfolgreich initialisiert",
|
||||
"license_undefined": "Undeiniert",
|
||||
"mail_alias_remove_failed": "E-Mail Alias '{:s}' konnte nicht entfernt werden",
|
||||
"mail_domain_unknown": "Unbekannte Mail Domain '{:s}'",
|
||||
"mail_forward_remove_failed": "Mailweiterleitung '{:s}' konnte nicht entfernt werden",
|
||||
"maindomain_change_failed": "Hauptdomain konnte nicht geändert werden",
|
||||
"maindomain_changed": "Hauptdomain wurde erfolgreich geändert",
|
||||
"monitor_disabled": "Servermonitoring erfolgreich deaktiviert",
|
||||
"monitor_enabled": "Servermonitoring erfolgreich aktiviert",
|
||||
"monitor_glances_con_failed": "Verbindung mit Glances nicht möglich",
|
||||
"monitor_not_enabled": "Servermonitoring ist nicht aktiviert",
|
||||
"monitor_period_invalid": "Falscher Zeitraum",
|
||||
"monitor_stats_file_not_found": "Statistikdatei nicht gefunden",
|
||||
"monitor_stats_no_update": "Keine Monitoringstatistik zur Aktualisierung",
|
||||
"monitor_stats_period_unavailable": "Keine Statistiken für den gewählten Zeitraum verfügbar",
|
||||
"mountpoint_unknown": "Unbekannten Einhängepunkt",
|
||||
"mysql_db_creation_failed": "MySQL Datenbankerzeugung fehlgeschlagen",
|
||||
"mysql_db_init_failed": "MySQL Datenbankinitialisierung fehlgeschlagen",
|
||||
"mysql_db_initialized": "MySQL Datenbank erfolgreich initialisiert",
|
||||
"network_check_mx_ko": "Es ist kein DNS MX Eintrag vorhanden",
|
||||
"network_check_smtp_ko": "Ausgehender Mailverkehr (SMTP Port 25) scheint in deinem Netzwerk blockiert zu sein",
|
||||
"network_check_smtp_ok": "Ausgehender Mailverkehr (SMTP Port 25) ist blockiert",
|
||||
"new_domain_required": "Du musst eine neue Hauptdomain angeben",
|
||||
"no_appslist_found": "Keine Appliste gefunden",
|
||||
"no_internet_connection": "Der Server ist nicht mit dem Internet verbunden",
|
||||
"no_ipv6_connectivity": "Eine IPv6 Verbindung steht nicht zur Verfügung",
|
||||
"no_restore_script": "Es konnte kein Wiederherstellungsskript für '{app:s}' gefunden werden",
|
||||
"no_such_conf_file": "Datei {file:s}: konnte nicht kopiert werden, da diese nicht existiert",
|
||||
"packages_no_upgrade": "Es müssen keine Pakete aktualisiert werden",
|
||||
"packages_upgrade_critical_later": "Wichtiges Paket ({:s}) wird später aktualisiert",
|
||||
"packages_upgrade_failed": "Es konnten nicht alle Pakete aktualisiert werden",
|
||||
"path_removal_failed": "Pfad {:s} konnte nicht entfernt werden",
|
||||
"pattern_backup_archive_name": "Ein gültiger Dateiname kann nur aus alphanumerischen und -_. bestehen",
|
||||
"pattern_domain": "Muss ein gültiger Domainname sein (z.B. meine-domain.org)",
|
||||
"pattern_email": "Muss eine gültige E-Mail Adresse sein (z.B. someone@domain.org)",
|
||||
"pattern_firstname": "Muss ein gültiger Vorname sein",
|
||||
"pattern_lastname": "Muss ein gültiger Nachname sein",
|
||||
"pattern_listname": "Kann nur Alphanumerische Zeichen oder Unterstriche enthalten",
|
||||
"pattern_mailbox_quota": "Muss eine Größe inkl. b/k/M/G/T Suffix, oder 0 zum deaktivieren sein",
|
||||
"pattern_password": "Muss mindestens drei Zeichen lang sein",
|
||||
"pattern_port": "Es muss ein valider Port (zwischen 0 und 65535) angegeben werden",
|
||||
"pattern_port_or_range": "Muss ein valider Port (z.B. 0-65535) oder ein Bereich (z.B. 100:200) sein",
|
||||
"pattern_username": "Darf nur aus klein geschriebenen alphanumerischen Zeichen und Unterstrichen bestehen",
|
||||
"port_already_closed": "Port {} wurde bereits für {:s} Verbindungen geschlossen",
|
||||
"port_already_opened": "Der Port {} wird bereits von {:s} benutzt",
|
||||
"port_available": "Port {} ist verfügbar",
|
||||
"port_unavailable": "Der Port {} ist nicht verfügbar",
|
||||
"restore_action_required": "Du musst etwas zum Wiederherstellen auswählen",
|
||||
"restore_already_installed_app": "Es ist bereits eine App mit der ID '{app:s}' installiet",
|
||||
"restore_app_failed": "App '{app:s}' konnte nicht wiederhergestellt werden",
|
||||
"restore_cleaning_failed": "Temporäres Wiederherstellungsverzeichnis konnte nicht geleert werden",
|
||||
"restore_complete": "Wiederherstellung abgeschlossen",
|
||||
"restore_confirm_yunohost_installed": "Möchtest du die Wiederherstellung wirklich starten? [{answers:s}]",
|
||||
"restore_failed": "System kann nicht Wiederhergestellt werden",
|
||||
"restore_hook_unavailable": "Der Wiederherstellungshook '{hook:s}' steht auf deinem System nicht zur Verfügung",
|
||||
"restore_nothings_done": "Es wurde nicht wiederhergestellt",
|
||||
"restore_running_app_script": "Wiederherstellung wird ausfeührt für App '{app:s}'...",
|
||||
"restore_running_hooks": "Wiederherstellung wird gestartet...",
|
||||
"service_add_configuration": "Füge Konfigurationsdatei {file:s} hinzu",
|
||||
"service_add_failed": "Dienst '{:s}' kann nicht hinzugefügt werden",
|
||||
"service_added": "Service erfolgreich hinzugefügt",
|
||||
"service_already_started": "Der Dienst '{:s}' läutt bereits",
|
||||
"service_already_stopped": "Dienst '{:s}' wurde bereits gestoppt",
|
||||
"service_cmd_exec_failed": "Kommando '{:s}' kann nicht ausgeführt werden",
|
||||
"service_configuration_conflict": "Die Datei {file:s} wurde zwischenzeitlich verändert. Bitte übernehme die Änderungen manuell oder nutze die Option --force (diese wird alle Änderungen überschreiben).",
|
||||
"service_disable_failed": "Dienst'{:s}' konnte nicht deaktiviert werden",
|
||||
"service_disabled": "Der Dienst '{:s}' wurde erfolgreich deaktiviert",
|
||||
"service_enable_failed": "Dienst '{:s}' konnte nicht aktiviert werden",
|
||||
"service_enabled": "Dienst '{:s}' erfolgreich aktiviert",
|
||||
"service_no_log": "Für den Dienst '{:s}' kann kein Log angezeigt werden",
|
||||
"service_remove_failed": "Dienst '{:s}' konnte nicht entfernt werden",
|
||||
"service_removed": "Dienst erfolgreich enternt",
|
||||
"service_start_failed": "Dienst '{:s}' konnte nicht gestartet werden",
|
||||
"service_started": "der Dienst '{:s}' wurde erfolgreich gestartet",
|
||||
"service_status_failed": "Status von '{:s}' kann nicht festgestellt werden",
|
||||
"service_stop_failed": "Dienst '{:s}' kann nicht gestoppt werden",
|
||||
"service_stopped": "Dienst '{:s}' wurde erfolgreich beendet",
|
||||
"service_unknown": "Unbekannte Dienst '{:s}'",
|
||||
"services_configured": "Konfiguration erfolgreich erstellt",
|
||||
"show_diff": "Es gibt folgende Änderungen:\n{diff:s}",
|
||||
"ssowat_conf_generated": "Konfiguration von SSOwat erfolgreich",
|
||||
"ssowat_conf_updated": "Persistente SSOwat Einstellung erfolgreich aktualisiert",
|
||||
"system_upgraded": "System wurde erfolgreich aktualisiert",
|
||||
"system_username_exists": "Der Benutzername existiert bereits",
|
||||
"unbackup_app": "App '{app:s}' konnte nicht gespeichert werden",
|
||||
"unexpected_error": "Ein unerwarteter Fehler ist aufgetreten",
|
||||
"unit_unknown": "Unbekannte Einheit '{:s}'",
|
||||
"unlimit": "Kein Kontingent",
|
||||
"unrestore_app": "App '{app:s}' kann nicht Wiederhergestellt werden",
|
||||
"update_cache_failed": "Konnte APT cache nicht aktualisieren",
|
||||
"updating_apt_cache": "Liste der verfügbaren Pakete wird aktualisiert...",
|
||||
"upgrade_complete": "Upgrade vollständig",
|
||||
"upgrading_packages": "Pakete werden aktualisiert...",
|
||||
"upnp_dev_not_found": "Es konnten keine UPnP Geräte gefunden werden",
|
||||
"upnp_disabled": "UPnP wurde erfolgreich deaktiviert",
|
||||
"upnp_enabled": "UPnP wurde aktiviert",
|
||||
"upnp_port_open_failed": "UPnP Ports konnten nicht geöffnet werden",
|
||||
"user_created": "Benutzer erfolgreich erstellt",
|
||||
"user_creation_failed": "Nutzer konnte nicht erstellt werden",
|
||||
"user_deleted": "Benutzer wurde erfolgreich entfernt",
|
||||
"user_deletion_failed": "Nutzer konnte nicht gelöscht werden",
|
||||
"user_home_creation_failed": "Benutzer Home konnte nicht erstellt werden",
|
||||
"user_info_failed": "Nutzerinformationen können nicht angezeigt werden",
|
||||
"user_unknown": "Unbekannter Benutzer",
|
||||
"user_update_failed": "Benutzer kann nicht aktualisiert werden",
|
||||
"user_updated": "Benutzer wurde erfolgreich aktualisiert",
|
||||
"yunohost_already_installed": "YunoHost ist bereits installiert",
|
||||
"yunohost_ca_creation_failed": "Zertifikatsstelle konnte nicht erstellt werden",
|
||||
"yunohost_configured": "YunoHost wurde erfolgreich konfiguriert",
|
||||
"yunohost_installing": "YunoHost wird installiert...",
|
||||
"action_invalid": "Ungültige Aktion '{action:s}'",
|
||||
"admin_password": "Verwaltungspasswort",
|
||||
"admin_password_change_failed": "Passwort kann nicht geändert werden",
|
||||
"admin_password_changed": "Verwaltungspasswort wurde erfolgreich geändert",
|
||||
"app_already_installed": "{app:s} ist schon installiert",
|
||||
"app_argument_choice_invalid": "Invalide Auswahl für Argument '{name:s}'. Muss einer der folgenden Werte sein {choices:s}",
|
||||
"app_argument_invalid": "Das Argument '{name:s}' hat einen falschen Wert: {error:s}",
|
||||
"app_argument_required": "Argument '{name:s}' wird benötigt",
|
||||
"app_extraction_failed": "Installationsdateien konnten nicht entpackt werden",
|
||||
"app_id_invalid": "Falsche App ID",
|
||||
"app_install_files_invalid": "Ungültige Installationsdateien",
|
||||
"app_location_already_used": "Eine andere App ist bereits an diesem Ort installiert",
|
||||
"app_location_install_failed": "Die App kann an diesem Ort nicht installiert werden",
|
||||
"app_manifest_invalid": "Ungültiges App Manifest",
|
||||
"app_no_upgrade": "Keine Aktualisierungen für Apps verfügbar",
|
||||
"app_not_installed": "{app:s} ist nicht intalliert",
|
||||
"app_recent_version_required": "Für {:s} benötigt eine aktuellere Version von moulinette",
|
||||
"app_removed": "{app:s} wurde erfolgreich entfernt",
|
||||
"app_sources_fetch_failed": "Quelldateien konnten nicht abgerufen werden",
|
||||
"app_unknown": "Unbekannte App",
|
||||
"app_upgrade_failed": "Apps konnten nicht aktualisiert werden",
|
||||
"app_upgraded": "{app:s} wurde erfolgreich aktualisiert",
|
||||
"appslist_fetched": "Liste der Apps wurde erfolgreich heruntergelanden",
|
||||
"appslist_removed": "Appliste erfolgreich entfernt",
|
||||
"appslist_retrieve_error": "Entfernte App Liste kann nicht gezogen werden",
|
||||
"appslist_unknown": "Unbekannte App Liste",
|
||||
"ask_current_admin_password": "Derzeitiges Verwaltungspasswort",
|
||||
"ask_email": "E-Mail Adresse",
|
||||
"ask_firstname": "Vorname",
|
||||
"ask_lastname": "Nachname",
|
||||
"ask_list_to_remove": "Liste enternen",
|
||||
"ask_main_domain": "Hauptdomain",
|
||||
"ask_new_admin_password": "Neues Verwaltungskennwort",
|
||||
"ask_password": "Passwort",
|
||||
"backup_action_required": "Du musst etwas zum Speichern auswählen",
|
||||
"backup_app_failed": "Konnte keine Sicherung für '{app:s}' erstellen",
|
||||
"backup_archive_app_not_found": "App '{app:s}' konnte in keiner Datensicherung gefunden werden",
|
||||
"backup_archive_hook_not_exec": "Hook '{hook:s}' konnte für diese Datensicherung nicht ausgeführt werden",
|
||||
"backup_archive_name_exists": "Datensicherung mit dem selben Namen existiert bereits",
|
||||
"backup_archive_name_unknown": "Unbekanntes lokale Datensicherung mit Namen '{name:s}' gefunden",
|
||||
"backup_archive_open_failed": "Kann Sicherungsarchiv nicht öfnen",
|
||||
"backup_cleaning_failed": "Verzeichnis von temporäre Sicherungsdaten konnte nicht geleert werden",
|
||||
"backup_complete": "Datensicherung komplett",
|
||||
"backup_creating_archive": "Datensicherung wird erstellt...",
|
||||
"backup_delete_error": "Pfad '{path:s}' konnte nicht gelöscht werden",
|
||||
"backup_deleted": "Datensicherung erfolgreich gelöscht",
|
||||
"backup_extracting_archive": "Entpacke Sicherungsarchiv...",
|
||||
"backup_hook_unknown": "Datensicherungshook '{hook:s}' unbekannt",
|
||||
"backup_invalid_archive": "Ungültige Datensicherung",
|
||||
"backup_nothings_done": "Es gibt keine Änderungen zur Speicherung",
|
||||
"backup_output_directory_forbidden": "Verbotenes Ausgabeverzeichnis",
|
||||
"backup_output_directory_not_empty": "Ausgabeordner ist nicht leer",
|
||||
"backup_output_directory_required": "Für die Datensicherung muss ein Zielverzeichnis angegeben werden",
|
||||
"backup_running_app_script": "Datensicherung für App '{app:s}' wurd durchgeführt...",
|
||||
"backup_running_hooks": "Datensicherunghook wird ausgeführt...",
|
||||
"custom_app_url_required": "Es muss eine URL angegeben um deine benutzerdefinierte App {app:s} zu aktualisieren",
|
||||
"custom_appslist_name_required": "Du musst einen Namen für deine benutzerdefinierte Appliste angeben",
|
||||
"dnsmasq_isnt_installed": "dnsmasq scheint nicht installiert zu sein. Bitte führe 'apt-get remove bind9 && apt-get install dnsmasq' aus",
|
||||
"domain_cert_gen_failed": "Zertifikat konnte nicht erzeugt werden",
|
||||
"domain_created": "Domain erfolgreich erzeugt",
|
||||
"domain_creation_failed": "Konnte Domain nicht erzeugen",
|
||||
"domain_deleted": "Domain erfolgreich gelöscht",
|
||||
"domain_deletion_failed": "Konnte Domain nicht löschen",
|
||||
"domain_dyndns_already_subscribed": "Du hast dich schon für einen DynDNS-Domain angemeldet",
|
||||
"domain_dyndns_invalid": "Domain nicht mittels DynDNS nutzbar",
|
||||
"domain_dyndns_root_unknown": "Unbekannte DynDNS Hauptdomain",
|
||||
"domain_exists": "Die Domain existiert bereits",
|
||||
"domain_uninstall_app_first": "Mindestens eine App ist noch für diese Domain installiert. Bitte zuerst die App deinstallieren und erst dann die Domain löschen..",
|
||||
"domain_unknown": "Unbekannte Domain",
|
||||
"domain_zone_exists": "DNS Zonen Datei existiert bereits",
|
||||
"domain_zone_not_found": "DNS Zonen Datei kann nicht für Domäne {:s} gefunden werden",
|
||||
"done": "Erledigt.",
|
||||
"downloading": "Wird heruntergeladen...",
|
||||
"dyndns_cron_installed": "DynDNS Cronjob erfolgreich installiert",
|
||||
"dyndns_cron_remove_failed": "DynDNS Cronjob konnte nicht entfernt werden",
|
||||
"dyndns_cron_removed": "DynDNS Cronjob wurde erfolgreich gelöscht",
|
||||
"dyndns_ip_update_failed": "IP Adresse konnte nicht für DynDNS aktualisiert werden",
|
||||
"dyndns_ip_updated": "IP Adresse wurde erfolgreich für DynDNS aktualisiert",
|
||||
"dyndns_key_generating": "DNS Schlüssel wird generiert, das könnte eine Weile dauern...",
|
||||
"dyndns_registered": "DynDNS Domain erfolgreich registriert",
|
||||
"dyndns_registration_failed": "DynDNS Domain konnte nicht registriert werden: {error:s}",
|
||||
"dyndns_unavailable": "DynDNS Subdomain ist nicht verfügbar",
|
||||
"executing_command": "Führe Kommendo '{command:s}' aus...",
|
||||
"executing_script": "Skript '{script:s}' wird ausgeührt...",
|
||||
"extracting": "Wird entpackt...",
|
||||
"field_invalid": "Feld '{:s}' ist unbekannt",
|
||||
"firewall_reload_failed": "Firewall konnte nicht neu geladen werden",
|
||||
"firewall_reloaded": "Firewall erfolgreich neu geladen",
|
||||
"firewall_rules_cmd_failed": "Einzelne Firewallregeln konnten nicht übernommen werden. Mehr Informationen sind im Log zu finden.",
|
||||
"format_datetime_short": "%m/%d/%Y %I:%M %p",
|
||||
"hook_argument_missing": "Fehlend Argument '{:s}'",
|
||||
"hook_choice_invalid": "ungültige Wahl '{:s}'",
|
||||
"hook_exec_failed": "Skriptausführung fehlgeschlagen",
|
||||
"hook_exec_not_terminated": "Skriptausführung noch nicht beendet",
|
||||
"hook_list_by_invalid": "Ungültiger Wert zur Anzeige von Hooks",
|
||||
"hook_name_unknown": "Hook '{name:s}' ist nicht bekannt",
|
||||
"installation_complete": "Installation vollständig",
|
||||
"installation_failed": "Installation fehlgeschlagen",
|
||||
"ip6tables_unavailable": "ip6tables kann nicht verwendet werden. Du befindest dich entweder in einem Container, oder es wird nicht vom Kernel unterstützt.",
|
||||
"iptables_unavailable": "iptables kann nicht verwendet werden. Du befindest dich entweder in einem Container, oder es wird nicht vom Kernel unterstützt.",
|
||||
"ldap_initialized": "LDAP erfolgreich initialisiert",
|
||||
"license_undefined": "Undeiniert",
|
||||
"mail_alias_remove_failed": "E-Mail Alias '{mail:s}' konnte nicht entfernt werden",
|
||||
"mail_domain_unknown": "Unbekannte Mail Domain '{domain:s}'",
|
||||
"mail_forward_remove_failed": "Mailweiterleitung '{mail:s}' konnte nicht entfernt werden",
|
||||
"maindomain_change_failed": "Hauptdomain konnte nicht geändert werden",
|
||||
"maindomain_changed": "Hauptdomain wurde erfolgreich geändert",
|
||||
"monitor_disabled": "Servermonitoring erfolgreich deaktiviert",
|
||||
"monitor_enabled": "Servermonitoring erfolgreich aktiviert",
|
||||
"monitor_glances_con_failed": "Verbindung mit Glances nicht möglich",
|
||||
"monitor_not_enabled": "Servermonitoring ist nicht aktiviert",
|
||||
"monitor_period_invalid": "Falscher Zeitraum",
|
||||
"monitor_stats_file_not_found": "Statistikdatei nicht gefunden",
|
||||
"monitor_stats_no_update": "Keine Monitoringstatistik zur Aktualisierung",
|
||||
"monitor_stats_period_unavailable": "Keine Statistiken für den gewählten Zeitraum verfügbar",
|
||||
"mountpoint_unknown": "Unbekannten Einhängepunkt",
|
||||
"mysql_db_creation_failed": "MySQL Datenbankerzeugung fehlgeschlagen",
|
||||
"mysql_db_init_failed": "MySQL Datenbankinitialisierung fehlgeschlagen",
|
||||
"mysql_db_initialized": "MySQL Datenbank erfolgreich initialisiert",
|
||||
"network_check_mx_ko": "Es ist kein DNS MX Eintrag vorhanden",
|
||||
"network_check_smtp_ko": "Ausgehender Mailverkehr (SMTP Port 25) scheint in deinem Netzwerk blockiert zu sein",
|
||||
"network_check_smtp_ok": "Ausgehender Mailverkehr (SMTP Port 25) ist blockiert",
|
||||
"new_domain_required": "Du musst eine neue Hauptdomain angeben",
|
||||
"no_appslist_found": "Keine Appliste gefunden",
|
||||
"no_internet_connection": "Der Server ist nicht mit dem Internet verbunden",
|
||||
"no_ipv6_connectivity": "Eine IPv6 Verbindung steht nicht zur Verfügung",
|
||||
"no_restore_script": "Es konnte kein Wiederherstellungsskript für '{app:s}' gefunden werden",
|
||||
"no_such_conf_file": "Datei {file:s}: konnte nicht kopiert werden, da diese nicht existiert",
|
||||
"packages_no_upgrade": "Es müssen keine Pakete aktualisiert werden",
|
||||
"packages_upgrade_critical_later": "Wichtiges Paket ({packages:s}) wird später aktualisiert",
|
||||
"packages_upgrade_failed": "Es konnten nicht alle Pakete aktualisiert werden",
|
||||
"path_removal_failed": "Pfad {:s} konnte nicht entfernt werden",
|
||||
"pattern_backup_archive_name": "Ein gültiger Dateiname kann nur aus alphanumerischen und -_. bestehen",
|
||||
"pattern_domain": "Muss ein gültiger Domainname sein (z.B. meine-domain.org)",
|
||||
"pattern_email": "Muss eine gültige E-Mail Adresse sein (z.B. someone@domain.org)",
|
||||
"pattern_firstname": "Muss ein gültiger Vorname sein",
|
||||
"pattern_lastname": "Muss ein gültiger Nachname sein",
|
||||
"pattern_listname": "Kann nur Alphanumerische Zeichen oder Unterstriche enthalten",
|
||||
"pattern_mailbox_quota": "Muss eine Größe inkl. b/k/M/G/T Suffix, oder 0 zum deaktivieren sein",
|
||||
"pattern_password": "Muss mindestens drei Zeichen lang sein",
|
||||
"pattern_port": "Es muss ein valider Port (zwischen 0 und 65535) angegeben werden",
|
||||
"pattern_port_or_range": "Muss ein valider Port (z.B. 0-65535) oder ein Bereich (z.B. 100:200) sein",
|
||||
"pattern_username": "Darf nur aus klein geschriebenen alphanumerischen Zeichen und Unterstrichen bestehen",
|
||||
"port_already_closed": "Port {port:d} wurde bereits für {ip_version:s} Verbindungen geschlossen",
|
||||
"port_already_opened": "Der Port {port:d} wird bereits von {ip_version:s} benutzt",
|
||||
"port_available": "Port {port:d} ist verfügbar",
|
||||
"port_unavailable": "Der Port {port:d} ist nicht verfügbar",
|
||||
"restore_action_required": "Du musst etwas zum Wiederherstellen auswählen",
|
||||
"restore_already_installed_app": "Es ist bereits eine App mit der ID '{app:s}' installiet",
|
||||
"restore_app_failed": "App '{app:s}' konnte nicht wiederhergestellt werden",
|
||||
"restore_cleaning_failed": "Temporäres Wiederherstellungsverzeichnis konnte nicht geleert werden",
|
||||
"restore_complete": "Wiederherstellung abgeschlossen",
|
||||
"restore_confirm_yunohost_installed": "Möchtest du die Wiederherstellung wirklich starten? [{answers:s}]",
|
||||
"restore_failed": "System kann nicht Wiederhergestellt werden",
|
||||
"restore_hook_unavailable": "Der Wiederherstellungshook '{hook:s}' steht auf deinem System nicht zur Verfügung",
|
||||
"restore_nothings_done": "Es wurde nicht wiederhergestellt",
|
||||
"restore_running_app_script": "Wiederherstellung wird ausfeührt für App '{app:s}'...",
|
||||
"restore_running_hooks": "Wiederherstellung wird gestartet...",
|
||||
"service_add_configuration": "Füge Konfigurationsdatei {file:s} hinzu",
|
||||
"service_add_failed": "Dienst '{service:s}' kann nicht hinzugefügt werden",
|
||||
"service_added": "Service erfolgreich hinzugefügt",
|
||||
"service_already_started": "Der Dienst '{service:s}' läutt bereits",
|
||||
"service_already_stopped": "Dienst '{service:s}' wurde bereits gestoppt",
|
||||
"service_cmd_exec_failed": "Kommando '{command:s}' kann nicht ausgeführt werden",
|
||||
"service_configuration_conflict": "Die Datei {file:s} wurde zwischenzeitlich verändert. Bitte übernehme die Änderungen manuell oder nutze die Option --force (diese wird alle Änderungen überschreiben).",
|
||||
"service_disable_failed": "Dienst '{service:s}' konnte nicht deaktiviert werden",
|
||||
"service_disabled": "Der Dienst '{service:s}' wurde erfolgreich deaktiviert",
|
||||
"service_enable_failed": "Dienst '{service:s}' konnte nicht aktiviert werden",
|
||||
"service_enabled": "Dienst '{service:s}' erfolgreich aktiviert",
|
||||
"service_no_log": "Für den Dienst '{service:s}' kann kein Log angezeigt werden",
|
||||
"service_remove_failed": "Dienst '{service:s}' konnte nicht entfernt werden",
|
||||
"service_removed": "Dienst erfolgreich enternt",
|
||||
"service_start_failed": "Dienst '{service:s}' konnte nicht gestartet werden",
|
||||
"service_started": "der Dienst '{service:s}' wurde erfolgreich gestartet",
|
||||
"service_status_failed": "Status von '{service:s}' kann nicht festgestellt werden",
|
||||
"service_stop_failed": "Dienst '{service:s}' kann nicht gestoppt werden",
|
||||
"service_stopped": "Dienst '{service:s}' wurde erfolgreich beendet",
|
||||
"service_unknown": "Unbekannte Dienst '{service:s}'",
|
||||
"services_configured": "Konfiguration erfolgreich erstellt",
|
||||
"show_diff": "Es gibt folgende Änderungen:\n{diff:s}",
|
||||
"ssowat_conf_generated": "Konfiguration von SSOwat erfolgreich",
|
||||
"ssowat_conf_updated": "Persistente SSOwat Einstellung erfolgreich aktualisiert",
|
||||
"system_upgraded": "System wurde erfolgreich aktualisiert",
|
||||
"system_username_exists": "Der Benutzername existiert bereits",
|
||||
"unbackup_app": "App '{app:s}' konnte nicht gespeichert werden",
|
||||
"unexpected_error": "Ein unerwarteter Fehler ist aufgetreten",
|
||||
"unit_unknown": "Unbekannte Einheit '{unit:s}'",
|
||||
"unlimit": "Kein Kontingent",
|
||||
"unrestore_app": "App '{app:s}' kann nicht Wiederhergestellt werden",
|
||||
"update_cache_failed": "Konnte APT cache nicht aktualisieren",
|
||||
"updating_apt_cache": "Liste der verfügbaren Pakete wird aktualisiert...",
|
||||
"upgrade_complete": "Upgrade vollständig",
|
||||
"upgrading_packages": "Pakete werden aktualisiert...",
|
||||
"upnp_dev_not_found": "Es konnten keine UPnP Geräte gefunden werden",
|
||||
"upnp_disabled": "UPnP wurde erfolgreich deaktiviert",
|
||||
"upnp_enabled": "UPnP wurde aktiviert",
|
||||
"upnp_port_open_failed": "UPnP Ports konnten nicht geöffnet werden",
|
||||
"user_created": "Benutzer erfolgreich erstellt",
|
||||
"user_creation_failed": "Nutzer konnte nicht erstellt werden",
|
||||
"user_deleted": "Benutzer wurde erfolgreich entfernt",
|
||||
"user_deletion_failed": "Nutzer konnte nicht gelöscht werden",
|
||||
"user_home_creation_failed": "Benutzer Home konnte nicht erstellt werden",
|
||||
"user_info_failed": "Nutzerinformationen können nicht angezeigt werden",
|
||||
"user_unknown": "Unbekannter Benutzer",
|
||||
"user_update_failed": "Benutzer kann nicht aktualisiert werden",
|
||||
"user_updated": "Benutzer wurde erfolgreich aktualisiert",
|
||||
"yunohost_already_installed": "YunoHost ist bereits installiert",
|
||||
"yunohost_ca_creation_failed": "Zertifikatsstelle konnte nicht erstellt werden",
|
||||
"yunohost_configured": "YunoHost wurde erfolgreich konfiguriert",
|
||||
"yunohost_installing": "YunoHost wird installiert...",
|
||||
"yunohost_not_installed": "Die YunoHost ist unvollständig. Bitte 'yunohost tools postinstall' ausführen."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
"custom_app_url_required" : "You must provide an URL to upgrade your custom app {app:s}",
|
||||
"app_requirements_checking" : "Checking required packages...",
|
||||
"app_requirements_unmeet" : "Requirements are not met, the package {pkgname} ({version}) must be {spec}",
|
||||
"app_requirements_failed" : "Unable to meet requirements: {err}",
|
||||
"app_requirements_failed" : "Unable to meet requirements: {error}",
|
||||
"app_upgraded" : "{app:s} successfully upgraded",
|
||||
"app_upgrade_failed" : "Unable to upgrade {app:s}",
|
||||
"app_id_invalid" : "Invalid app id",
|
||||
|
@ -34,6 +34,8 @@
|
|||
"app_extraction_failed" : "Unable to extract installation files",
|
||||
"app_install_files_invalid" : "Invalid installation files",
|
||||
"app_manifest_invalid" : "Invalid app manifest",
|
||||
"app_incompatible" : "The app is incompatible with your YunoHost version",
|
||||
"app_package_need_update" : "The app package need to be updated to follow YunoHost changes",
|
||||
"app_argument_choice_invalid" : "Invalid choice for argument '{name:s}', it must be one of {choices:s}",
|
||||
"app_argument_invalid" : "Invalid value for argument '{name:s}': {error:s}",
|
||||
"app_argument_required" : "Argument '{name:s}' is required",
|
||||
|
@ -128,12 +130,20 @@
|
|||
"service_status_failed" : "Unable to determine status of service '{service:s}'",
|
||||
"service_no_log" : "No log to display for service '{service:s}'",
|
||||
"service_cmd_exec_failed" : "Unable to execute command '{command:s}'",
|
||||
"service_configured": "Configuration successfully generated for service '{service:s}'",
|
||||
"service_configured_all": "Configuration successfully generated for every services",
|
||||
"service_configuration_conflict": "The file {file:s} has been changed since its last generation. Please apply the modifications manually or use the option --force (it will erase all the modifications previously done to the file).",
|
||||
"no_such_conf_file": "Unable to copy the file {file:s}: the file does not exist",
|
||||
"service_add_configuration": "Adding the configuration file {file:s}",
|
||||
"show_diff": "Here are the differences:\n{diff:s}",
|
||||
"service_regenconf_failed" : "Unable to regenerate the configuration for service(s): {services}",
|
||||
"service_regenconf_pending_applying" : "Applying pending configuration for service '{service}'...",
|
||||
"service_regenconf_dry_pending_applying" : "Checking pending configuration which would have been applied for service '{service}'...",
|
||||
"service_conf_file_manually_removed" : "The configuration file '{conf}' has been manually removed and will not be created",
|
||||
"service_conf_file_manually_modified" : "The configuration file '{conf}' has been manually modified and will not be updated",
|
||||
"service_conf_file_not_managed" : "The configuration file '{conf}' is not managed yet and will not be updated",
|
||||
"service_conf_file_backed_up" : "The configuration file '{conf}' has been backed up to '{backup}'",
|
||||
"service_conf_file_removed" : "The configuration file '{conf}' has been removed",
|
||||
"service_conf_file_remove_failed" : "Unable to remove the configuration file '{conf}'",
|
||||
"service_conf_file_updated" : "The configuration file '{conf}' has been updated",
|
||||
"service_conf_file_copy_failed" : "Unable to copy the new configuration file '{new}' to '{conf}'",
|
||||
"service_conf_up_to_date" : "The configuration is already up-to-date for service '{service}'",
|
||||
"service_conf_updated" : "The configuration has been updated for service '{service}'",
|
||||
"service_conf_would_be_updated" : "The configuration would have been updated for service '{service}'",
|
||||
|
||||
"network_check_smtp_ok" : "Outbound mail (SMTP port 25) is not blocked",
|
||||
"network_check_smtp_ko" : "Outbound mail (SMTP port 25) seems to be blocked by your network",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"action_invalid": "Acción inválida '{:s}'",
|
||||
"action_invalid": "Acción inválida '{action:s}'",
|
||||
"admin_password": "Contraseña administrativa",
|
||||
"admin_password_change_failed": "No se pudo cambiar la contraseña",
|
||||
"admin_password_changed": "Contraseña administrativa se cambió con éxito",
|
||||
"app_already_installed": "{:s} ya está instalado ",
|
||||
"app_already_installed": "{app:s} ya está instalado",
|
||||
"app_extraction_failed": "No se pudo extraer los archivos de instalación ",
|
||||
"app_id_invalid": "id de la aplicación inválida ",
|
||||
"app_install_files_invalid": "Archivos de instalación inválidos ",
|
||||
|
@ -11,13 +11,13 @@
|
|||
"app_location_install_failed": "No se pudo instalar la aplicación en esta lugar",
|
||||
"app_manifest_invalid": "Manifesto de la aplicación es inválido",
|
||||
"app_no_upgrade": "Ninguna app a actualizar",
|
||||
"app_not_installed": "{:s} no está instalado.",
|
||||
"app_not_installed": "{app:s} no está instalado",
|
||||
"app_recent_version_required": "{:s} requiere una versión más reciente de moulinette ",
|
||||
"app_removed": "{:s} era eliminado con éxito ",
|
||||
"app_removed": "{app:s} era eliminado con éxito",
|
||||
"app_sources_fetch_failed": "No se pudo descargar los archivos de códigos fuentes",
|
||||
"app_unknown": "App desconocida",
|
||||
"app_upgrade_failed": "No se pudo actualizar todas las aplicaciones ",
|
||||
"app_upgraded": "{:s} actualizado con éxito",
|
||||
"app_upgraded": "{app:s} actualizado con éxito",
|
||||
"appslist_fetched": "Lista de aplicaciones se trajo con éxito",
|
||||
"appslist_removed": "Lista de aplicaciones se eliminó con éxito",
|
||||
"appslist_retrieve_error": "No se pudo recuperar la lista de aplicaciones a distancia ",
|
||||
|
@ -41,7 +41,7 @@
|
|||
"backup_output_directory_not_empty": "La carpeta de salida no está vacía",
|
||||
"backup_output_directory_required": "Debe proporcionar un directorio de salida para el backup",
|
||||
"backup_running_hooks": "Ejecutando los hooks de backup...",
|
||||
"custom_app_url_required": " Debe proporcionar una URL para actualizar su aplicación personalizada {:s} ",
|
||||
"custom_app_url_required": "Debe proporcionar una URL para actualizar su aplicación personalizada {app:s}",
|
||||
"custom_appslist_name_required": "Debe proporcionar un nombre para la lista de aplicaciones personalizadas ",
|
||||
"dnsmasq_isnt_installed": "Parece que dnsmasq no está instalado, por favor, ejecuta 'apt-get remove bind9 && apt-get install dnsmasq'",
|
||||
"domain_cert_gen_failed": "No se pudo crear certificado",
|
||||
|
@ -66,7 +66,7 @@
|
|||
"dyndns_ip_updated": "La dirección IP era actualizado en DynDNS con éxito",
|
||||
"dyndns_key_generating": "Generación del llave de DNS está en curso. Este podría durar unos momentos...",
|
||||
"dyndns_registered": "El dominio DynDNS era registrado con éxito.",
|
||||
"dyndns_registration_failed": "No se pudo registrar el dominio DynDNS: {:s}",
|
||||
"dyndns_registration_failed": "No se pudo registrar el dominio DynDNS: {error:s}",
|
||||
"dyndns_unavailable": "Subdominio DynDNS no disponible",
|
||||
"executing_script": "Ejecutando script...",
|
||||
"extracting": "Extrayendo...",
|
||||
|
@ -77,16 +77,16 @@
|
|||
"hook_argument_missing": "Falta un parámetro '{:s}'",
|
||||
"hook_choice_invalid": "Selección inválida '{:s}'",
|
||||
"hook_list_by_invalid": "La propiedad de este hook es inválida",
|
||||
"hook_name_unknown": "Hook desconocido '{:s}'",
|
||||
"hook_name_unknown": "Hook desconocido '{name:s}'",
|
||||
"installation_complete": "La instalación se ha completado",
|
||||
"installation_failed": "La Instalación se ha fracasado",
|
||||
"ip6tables_unavailable": "No puedes modificar los ip6tables aquí. Eres en un contenedor o su kernel no soporte este opción.",
|
||||
"iptables_unavailable": "No puedes modificar los iptables aquí. Eres en un contenedor o su kernel no soporte este opción.",
|
||||
"ldap_initialized": "LDAP se inició con éxito",
|
||||
"license_undefined": "indefinido",
|
||||
"mail_alias_remove_failed": "No se pudo quitar el alias de correos '{:s}'",
|
||||
"mail_domain_unknown": "El dominio de correos '{:s}' es desconocido",
|
||||
"mail_forward_remove_failed": "No se pudo quitar la reenvía de correos '{:s}'",
|
||||
"mail_alias_remove_failed": "No se pudo quitar el alias de correos '{mail:s}'",
|
||||
"mail_domain_unknown": "El dominio de correos '{domain:s}' es desconocido",
|
||||
"mail_forward_remove_failed": "No se pudo quitar la reenvía de correos '{mail:s}'",
|
||||
"maindomain_change_failed": "No se pudo cambiar el dominio principal",
|
||||
"maindomain_changed": "Dominio principal se cambió con éxito",
|
||||
"monitor_disabled": "Supervisión del sistema era desactivado con éxito",
|
||||
|
@ -105,7 +105,7 @@
|
|||
"no_appslist_found": "No se encontró ninguna lista de Apps",
|
||||
"no_internet_connection": "El servidor no está conectado al Internet.",
|
||||
"packages_no_upgrade": "No hay actualización por ningun paquete",
|
||||
"packages_upgrade_critical_later": "Los paquetes críticos ({:s}) se actualizarán más tarde",
|
||||
"packages_upgrade_critical_later": "Los paquetes críticos ({packages:s}) se actualizarán más tarde",
|
||||
"packages_upgrade_failed": "No se pudo actualizar todo de los paquetes",
|
||||
"path_removal_failed": "No se pudo quitar la ruta {:s}",
|
||||
"pattern_backup_archive_name": "Debe que ser un nombre de archivo válido con los caracteres alfanumericos, o los -_.",
|
||||
|
@ -118,39 +118,39 @@
|
|||
"pattern_port": "El numéro del puerto debe ser válido (i.e. 0-65535)",
|
||||
"pattern_port_or_range": "El numéro del puerto debe ser válido (i.e. 0-65535) o un intervalo de puertos (e.g. 100:200)",
|
||||
"pattern_username": "Debe contener solamente caracteres alfanuméricos o la guion bajo",
|
||||
"port_already_closed": "El puerto {} ya está cerrado por {:s} connecciones.",
|
||||
"port_already_opened": "El puerto {} ya está abierto por {:s} connecciones",
|
||||
"port_available": "El puerto {} está disponible",
|
||||
"port_unavailable": "El puerto {} no está disponible",
|
||||
"port_already_closed": "El puerto {port:d} ya está cerrado por {ip_version:s} connecciones",
|
||||
"port_already_opened": "El puerto {port:d} ya está abierto por {ip_version:s} connecciones",
|
||||
"port_available": "El puerto {port:d} está disponible",
|
||||
"port_unavailable": "El puerto {port:d} no está disponible",
|
||||
"restore_complete": "Restauración se ha completado",
|
||||
"restore_confirm_yunohost_installed": "Estás seguro que quieres restaurar a un sistema que ya está instalado? [{answers:s}]",
|
||||
"restore_failed": "No se pudo restaurar el sistema",
|
||||
"restore_running_hooks": "Ejecutando hooks de restauración...",
|
||||
"service_add_failed": "No se pudo añadir el servicio '{:s}'",
|
||||
"service_add_failed": "No se pudo añadir el servicio '{service:s}'",
|
||||
"service_added": "Servicio añadido con éxito",
|
||||
"service_already_started": "El servicio '{:s}' ya se ha empezado",
|
||||
"service_already_stopped": "El servicio '{:s}' ya está parado ",
|
||||
"service_cmd_exec_failed": "No se pudo ejecutar comando '{:s}'",
|
||||
"service_disable_failed": "No se pudo desactivar el servicio '{:s}'",
|
||||
"service_disabled": "Servicio '{:s}' desactivado con éxito",
|
||||
"service_enable_failed": "No se pudo activar el servicio '{:s}'",
|
||||
"service_enabled": "Servicio '{:s}' activado con éxito",
|
||||
"service_no_log": "No hay archivo historial del servicio '{:s}' a exhibir",
|
||||
"service_remove_failed": "No se pudo quitar el servicio '{:s}'",
|
||||
"service_already_started": "El servicio '{service:s}' ya se ha empezado",
|
||||
"service_already_stopped": "El servicio '{service:s}' ya está parado",
|
||||
"service_cmd_exec_failed": "No se pudo ejecutar comando '{command:s}'",
|
||||
"service_disable_failed": "No se pudo desactivar el servicio '{service:s}'",
|
||||
"service_disabled": "Servicio '{service:s}' desactivado con éxito",
|
||||
"service_enable_failed": "No se pudo activar el servicio '{service:s}'",
|
||||
"service_enabled": "Servicio '{service:s}' activado con éxito",
|
||||
"service_no_log": "No hay archivo historial del servicio '{service:s}' a exhibir",
|
||||
"service_remove_failed": "No se pudo quitar el servicio '{service:s}'",
|
||||
"service_removed": "Servicio quitado con éxito",
|
||||
"service_start_failed": "No se pudo empezar el servicio '{:s}'",
|
||||
"service_started": "El servicio '{:s}' se empezó con éxito",
|
||||
"service_status_failed": "No se pudo discernir el estado del servicio '{:s}'",
|
||||
"service_stop_failed": "No se pudo parar el servicio '{:s}'",
|
||||
"service_stopped": "Servicio '{:s}' parado con éxito",
|
||||
"service_unknown": "Servicio desconocido '{:s}'",
|
||||
"service_start_failed": "No se pudo empezar el servicio '{service:s}'",
|
||||
"service_started": "El servicio '{service:s}' se empezó con éxito",
|
||||
"service_status_failed": "No se pudo discernir el estado del servicio '{service:s}'",
|
||||
"service_stop_failed": "No se pudo parar el servicio '{service:s}'",
|
||||
"service_stopped": "Servicio '{service:s}' parado con éxito",
|
||||
"service_unknown": "Servicio desconocido '{service:s}'",
|
||||
"ssowat_conf_generated": "Configuración SSOwat generado con éxito ",
|
||||
"ssowat_conf_updated": "Configuración persistente SSOwat actualizada con éxito",
|
||||
"system_upgraded": "Actualización del sistema se ha completado con éxito.",
|
||||
"system_username_exists": "Nombre de usuario ya existe en los usuarios del sistema",
|
||||
"unbackup_app": "La App '{:s}' no será guardada",
|
||||
"unexpected_error": "Un error ha ocurrido",
|
||||
"unit_unknown": "Unidad '{:s}' desconocido",
|
||||
"unit_unknown": "Unidad '{unit:s}' desconocido",
|
||||
"unrestore_app": "La App '{:s}' no será restaurada",
|
||||
"update_cache_failed": "No se pudo actualizar el cache APT",
|
||||
"updating_apt_cache": "Actualizando la lista de paquetes disponibles...",
|
||||
|
|
449
locales/fr.json
449
locales/fr.json
|
@ -1,218 +1,235 @@
|
|||
{
|
||||
"action_invalid": "Action « {:s} » incorrecte",
|
||||
"admin_password": "Mot de passe d'administration",
|
||||
"admin_password_change_failed": "Impossible de modifier le mot de passe d'administration",
|
||||
"admin_password_changed": "Mot de passe d'administration modifié avec succès",
|
||||
"app_already_installed": "{app:s} est déjà installé",
|
||||
"app_argument_choice_invalid": "Choix invalide pour le paramètre « {name:s} », il doit être l'un de {choices:s}",
|
||||
"app_argument_invalid": "Valeur invalide pour le paramètre « {name:s} » : {error:s}",
|
||||
"app_argument_missing": "Paramètre manquant « {:s} »",
|
||||
"app_argument_required": "Le paramètre « {name:s} » est requis",
|
||||
"app_extraction_failed": "Impossible d'extraire les fichiers d'installation",
|
||||
"app_id_invalid": "Id d'application incorrect",
|
||||
"app_install_files_invalid": "Fichiers d'installation incorrects",
|
||||
"app_location_already_used": "Une application est déjà installée à cet emplacement",
|
||||
"app_location_install_failed": "Impossible d'installer l'application à cet emplacement",
|
||||
"app_manifest_invalid": "Manifeste d'application incorrect",
|
||||
"app_no_upgrade": "Aucune application à mettre à jour",
|
||||
"app_not_correctly_installed": "{app:s} semble être mal installé",
|
||||
"app_not_installed": "{app:s} n'est pas installé",
|
||||
"app_recent_version_required": "{app:s} nécessite une version plus récente de YunoHost",
|
||||
"app_removed": "{app:s} supprimé avec succès",
|
||||
"app_sources_fetch_failed": "Impossible de récupérer les fichiers sources",
|
||||
"app_unknown": "Application inconnue",
|
||||
"app_unsupported_remote_type": "Le type distant utilisé par l'application n'est pas supporté",
|
||||
"app_upgrade_failed": "Impossible de mettre à jour {app:s}",
|
||||
"app_upgraded": "{app:s} mis à jour avec succès",
|
||||
"appslist_fetched": "Liste d'applications récupérée avec succès",
|
||||
"appslist_removed": "Liste d'applications supprimée avec succès",
|
||||
"appslist_retrieve_error": "Impossible de récupérer la liste d'applications distante",
|
||||
"appslist_unknown": "Liste d'applications inconnue",
|
||||
"ask_current_admin_password": "Mot de passe d'administration actuel",
|
||||
"ask_email": "Adresse courriel",
|
||||
"ask_firstname": "Prénom",
|
||||
"ask_lastname": "Nom",
|
||||
"ask_list_to_remove": "Liste à supprimer",
|
||||
"ask_main_domain": "Domaine principal",
|
||||
"ask_new_admin_password": "Nouveau mot de passe d'administration",
|
||||
"ask_password": "Mot de passe",
|
||||
"backup_action_required": "Vous devez préciser ce qui est à sauvegarder",
|
||||
"backup_app_failed": "Impossible de sauvegarder l'application « {app:s} »",
|
||||
"backup_archive_app_not_found": "L'application « {app:s} » n'a pas été trouvée dans l'archive de la sauvegarde",
|
||||
"backup_archive_hook_not_exec": "Le script « {hook:s} » n'a pas été exécuté dans cette sauvegarde",
|
||||
"backup_archive_name_exists": "Une archive de sauvegarde avec ce nom existe déjà",
|
||||
"backup_archive_name_unknown": "L'archive locale de sauvegarde nommée « {name:s} » est inconnue",
|
||||
"backup_archive_open_failed": "Impossible d'ouvrir l'archive de sauvegarde",
|
||||
"backup_cleaning_failed": "Impossible de nettoyer le dossier temporaire de sauvegarde",
|
||||
"backup_complete": "Sauvegarde terminée",
|
||||
"backup_creating_archive": "Création de l'archive de sauvegarde...",
|
||||
"backup_delete_error": "Impossible de supprimer « {path:s} »",
|
||||
"backup_deleted": "La sauvegarde a bien été supprimée",
|
||||
"backup_extracting_archive": "Extraction de l'archive de sauvegarde...",
|
||||
"backup_hook_unknown": "Script de sauvegarde « {hook:s} » inconnu",
|
||||
"backup_invalid_archive": "Archive de sauvegarde incorrecte",
|
||||
"backup_nothings_done": "Il n'y a rien à sauvegarder",
|
||||
"backup_output_directory_forbidden": "Dossier de sortie interdit",
|
||||
"backup_output_directory_not_empty": "Le dossier de sortie n'est pas vide",
|
||||
"backup_output_directory_required": "Vous devez spécifier un dossier de sortie pour la sauvegarde",
|
||||
"backup_running_app_script": "Lancement du script de sauvegarde de l'application « {app:s} »...",
|
||||
"backup_running_hooks": "Exécution des scripts de sauvegarde...",
|
||||
"custom_app_url_required": "Vous devez spécifier une URL pour mettre à jour votre application locale {app:s}",
|
||||
"custom_appslist_name_required": "Vous devez spécifier un nom pour votre liste d'applications personnalisée",
|
||||
"dnsmasq_isnt_installed": "dnsmasq ne semble pas être installé, veuillez lancer « apt-get remove bind9 && apt-get install dnsmasq »",
|
||||
"domain_cert_gen_failed": "Impossible de générer le certificat",
|
||||
"domain_created": "Domaine créé avec succès",
|
||||
"domain_creation_failed": "Impossible de créer le domaine",
|
||||
"domain_deleted": "Domaine supprimé avec succès",
|
||||
"domain_deletion_failed": "Impossible de supprimer le domaine",
|
||||
"domain_dyndns_already_subscribed": "Vous avez déjà souscris à un domaine DynDNS",
|
||||
"domain_dyndns_invalid": "Domaine incorrect pour un usage avec DynDNS",
|
||||
"domain_dyndns_root_unknown": "Domaine DynDNS principal inconnu",
|
||||
"domain_exists": "Le domaine existe déjà",
|
||||
"domain_uninstall_app_first": "Une ou plusieurs applications sont installées sur ce domaine. Veuillez d'abord les désinstaller avant de supprimer ce domaine.",
|
||||
"domain_unknown": "Domaine inconnu",
|
||||
"domain_zone_exists": "Le fichier de zone DNS existe déjà",
|
||||
"domain_zone_not_found": "Fichier de zone DNS introuvable pour le domaine {:s}",
|
||||
"done": "Terminé.",
|
||||
"downloading": "Téléchargement...",
|
||||
"dyndns_cron_installed": "Tâche cron pour DynDNS installée avec succès",
|
||||
"dyndns_cron_remove_failed": "Impossible d'enlever la tâche cron pour DynDNS",
|
||||
"dyndns_cron_removed": "La tâche cron pour DynDNS a été enlevée avec succès",
|
||||
"dyndns_ip_update_failed": "Impossible de mettre à jour l'adresse IP sur le domaine DynDNS",
|
||||
"dyndns_ip_updated": "Adresse IP mise à jour avec succès sur le domaine DynDNS",
|
||||
"dyndns_key_generating": "La clé DNS est en cours de génération, cela peut prendre du temps...",
|
||||
"dyndns_registered": "Domaine DynDNS enregistré avec succès",
|
||||
"dyndns_registration_failed": "Impossible d'enregistrer le domaine DynDNS : {:s}",
|
||||
"dyndns_unavailable": "Sous-domaine DynDNS indisponible",
|
||||
"executing_command": "Exécution de la commande « {command:s} »...",
|
||||
"executing_script": "Exécution du script « {script:s} »...",
|
||||
"extracting": "Extraction...",
|
||||
"field_invalid": "Champ incorrect : « {:s} »",
|
||||
"firewall_reload_failed": "Impossible de recharger le pare-feu",
|
||||
"firewall_reloaded": "Pare-feu rechargé avec succès",
|
||||
"firewall_rules_cmd_failed": "Certaines règles du pare-feu n'ont pas pu être appliquées. Pour plus d'informations, consultez le journal.",
|
||||
"format_datetime_short": "%d/%m/%Y %H:%M",
|
||||
"hook_argument_missing": "Argument manquant : '{:s}'",
|
||||
"hook_choice_invalid": "Choix incorrect : '{:s}'",
|
||||
"hook_exec_failed": "Échec de l'exécution du script",
|
||||
"hook_exec_not_terminated": "L'exécution du script ne s'est pas terminée",
|
||||
"hook_list_by_invalid": "Propriété pour lister les scripts incorrecte",
|
||||
"hook_name_unknown": "Nom de script « {:s} » inconnu",
|
||||
"installation_complete": "Installation terminée",
|
||||
"installation_failed": "Échec de l'installation",
|
||||
"ip6tables_unavailable": "Vous ne pouvez pas jouer avec ip6tables ici. Vous êtes sûrement dans un conteneur, ou alors votre noyau ne le supporte pas.",
|
||||
"iptables_unavailable": "Vous ne pouvez pas jouer avec iptables ici. Vous êtes sûrement dans un conteneur, autrement votre noyau ne le supporte pas.",
|
||||
"ldap_initialized": "Répertoire LDAP initialisé avec succès",
|
||||
"license_undefined": "indéfinie",
|
||||
"mail_alias_remove_failed": "Impossible de supprimer l'adresse mail supplémentaire « {:s} »",
|
||||
"mail_domain_unknown": "Domaine « {:s} » de l'adresse mail inconnu",
|
||||
"mail_forward_remove_failed": "Impossible de supprimer l'adresse courriel de transfert « {:s} »",
|
||||
"maindomain_change_failed": "Impossible de modifier le domaine principal",
|
||||
"maindomain_changed": "Domaine principal modifié avec succès",
|
||||
"monitor_disabled": "Le suivi de l'état du serveur a été désactivé avec succès",
|
||||
"monitor_enabled": "Suivi de l'état du serveur activé avec succès",
|
||||
"monitor_glances_con_failed": "Impossible de se connecter au serveur Glances",
|
||||
"monitor_not_enabled": "Le suivi de l'état du serveur n'est pas activé",
|
||||
"monitor_period_invalid": "Période de temps incorrecte",
|
||||
"monitor_stats_file_not_found": "Le fichier de statistiques est introuvable",
|
||||
"monitor_stats_no_update": "Aucune donnée de l'état du serveur à mettre à jour",
|
||||
"monitor_stats_period_unavailable": "Aucune statistique n'est disponible pour la période",
|
||||
"mountpoint_unknown": "Point de montage inconnu",
|
||||
"mysql_db_creation_failed": "Impossible de créer la base de données MySQL",
|
||||
"mysql_db_init_failed": "Impossible d'initialiser la base de données MySQL",
|
||||
"mysql_db_initialized": "Base de donnée MySQL initialisée avec succès",
|
||||
"network_check_mx_ko": "L'enregistrement DNS MX n'est pas précisé",
|
||||
"network_check_smtp_ko": "Le trafic mail sortant (port 25 SMTP) semble bloqué par votre réseau",
|
||||
"network_check_smtp_ok": "Le trafic courriel sortant (port 25 SMTP) n'est pas bloqué",
|
||||
"new_domain_required": "Vous devez spécifier le nouveau domaine principal",
|
||||
"no_appslist_found": "Aucune liste d'applications trouvée",
|
||||
"no_internet_connection": "Le serveur n'est pas connecté à internet",
|
||||
"no_ipv6_connectivity": "La connectivité IPv6 n'est pas disponible",
|
||||
"no_restore_script": "Le script de sauvegarde n'a pas été trouvé pour l'application « {app:s} »",
|
||||
"no_such_conf_file": "Le fichier {file:s} n’existe pas, il ne peut pas être copié",
|
||||
"not_enough_disk_space": "L'espace disque est insuffisant sur « {path:s} »",
|
||||
"packages_no_upgrade": "Il n'y a aucun paquet à mettre à jour",
|
||||
"packages_upgrade_critical_later": "Les paquets critiques ({:s}) seront mis à jour ultérieurement",
|
||||
"packages_upgrade_failed": "Impossible de mettre à jour tous les paquets",
|
||||
"path_removal_failed": "Impossible de supprimer le chemin {:s}",
|
||||
"pattern_backup_archive_name": "Doit être un nom de fichier valide composé de caractères alphanumérique et -_. uniquement",
|
||||
"pattern_domain": "Doit être un nom de domaine valide (ex : mon-domaine.org)",
|
||||
"pattern_email": "Doit être une adresse courriel valide (ex. : someone@domain.org)",
|
||||
"pattern_firstname": "Doit être un prénom valide",
|
||||
"pattern_lastname": "Doit être un nom valide",
|
||||
"pattern_listname": "Doit être composé uniquement de caractères alphanumériques et de tirets bas",
|
||||
"pattern_mailbox_quota": "Doit être une taille avec le suffixe b/k/M/G/T ou 0 pour désactiver le quota",
|
||||
"pattern_password": "Doit être composé d'au moins 3 caractères",
|
||||
"pattern_port": "Doit être un numéro de port valide (ex. : 0-65535)",
|
||||
"pattern_port_or_range": "Doit être un numéro de port valide (ex. : 0-65535) ou une gamme de ports (ex. : 100:200)",
|
||||
"pattern_positive_number": "Doit être un nombre positif",
|
||||
"pattern_username": "Doit être composé uniquement de caractères alphanumériques minuscules et de tirets bas",
|
||||
"port_already_closed": "Le port {} est déjà fermé pour les connexions {:s}",
|
||||
"port_already_opened": "Le port {} est déjà ouvert pour les connexions {:s}",
|
||||
"port_available": "Le port {port:d} est disponible",
|
||||
"port_unavailable": "Le port {port:d} n'est pas disponible",
|
||||
"restore_action_required": "Vous devez préciser ce qui est à restaurer",
|
||||
"restore_already_installed_app": "Une application est déjà installée avec l'id « {app:s} »",
|
||||
"restore_app_failed": "Impossible de restaurer l'application « {app:s} »",
|
||||
"restore_cleaning_failed": "Impossible de nettoyer le dossier temporaire de restauration",
|
||||
"restore_complete": "Restauration terminée",
|
||||
"restore_confirm_yunohost_installed": "Voulez-vous vraiment restaurer un système déjà installé ? [{answers:s}]",
|
||||
"restore_failed": "Impossible de restaurer le système",
|
||||
"restore_hook_unavailable": "Le script de restauration « {hook:s} » n'est pas disponible sur votre système",
|
||||
"restore_nothings_done": "Rien n'a été restauré",
|
||||
"restore_running_app_script": "Lancement du script de restauration pour l'application « {app:s} »...",
|
||||
"restore_running_hooks": "Exécution des scripts de restauration...",
|
||||
"service_add_configuration": "Ajout du fichier de configuration {file:s}",
|
||||
"service_add_failed": "Impossible d'ajouter le service « {:s} »",
|
||||
"service_added": "Service ajouté avec succès",
|
||||
"service_already_started": "Le service « {:s} » est déjà démarré",
|
||||
"service_already_stopped": "Le service « {:s} » est déjà arrêté",
|
||||
"service_cmd_exec_failed": "Impossible d'exécuter la commande « {:s} »",
|
||||
"service_configuration_conflict": "Le fichier {file:s} a été modifié depuis sa dernière génération. Veuillez y appliquer les modifications manuellement ou utiliser l’option --force (ce qui écrasera toutes les modifications effectuées sur le fichier).",
|
||||
"service_disable_failed": "Impossible de désactiver le service « {:s} »",
|
||||
"service_disabled": "Service « {:s} » désactivé avec succès",
|
||||
"service_enable_failed": "Impossible d'activer le service « {:s} »",
|
||||
"service_enabled": "Service « {:s} » activé avec succès",
|
||||
"service_no_log": "Aucun journal à afficher pour le service « {:s} »",
|
||||
"service_remove_failed": "Impossible d'enlever le service « {:s} »",
|
||||
"service_removed": "Service enlevé avec succès",
|
||||
"service_start_failed": "Impossible de démarrer le service « {:s} »",
|
||||
"service_started": "Le service « {:s} » a démarré avec succès",
|
||||
"service_status_failed": "Impossible de déterminer le statut du service « {:s} »",
|
||||
"service_stop_failed": "Impossible d'arrêter le service « {:s} »",
|
||||
"service_stopped": "Service « {:s} » arrêté avec succès",
|
||||
"service_unknown": "Service « {:s} » inconnu",
|
||||
"services_configured": "La configuration a été générée avec succès",
|
||||
"show_diff": "Voici les différences :\n{diff:s}",
|
||||
"ssowat_conf_generated": "Configuration de SSOwat générée avec succès",
|
||||
"ssowat_conf_updated": "La configuration persistante de SSOwat a été mise à jour avec succès",
|
||||
"system_upgraded": "Système mis à jour avec succès",
|
||||
"system_username_exists": "Le nom d'utilisateur existe déjà dans les utilisateurs système",
|
||||
"unbackup_app": "L'application « {app:s} » ne sera pas sauvegardée",
|
||||
"unexpected_error": "Une erreur inattendue est survenue",
|
||||
"unit_unknown": "Unité « {:s} » inconnue",
|
||||
"unlimit": "Pas de quota",
|
||||
"unrestore_app": "L'application « {app:s} » ne sera pas restaurée",
|
||||
"update_cache_failed": "Impossible de mettre à jour le cache de l'APT",
|
||||
"updating_apt_cache": "Mise à jour de la liste des paquets disponibles...",
|
||||
"upgrade_complete": "Mise à jour terminée",
|
||||
"upgrading_packages": "Mise à jour des paquets...",
|
||||
"upnp_dev_not_found": "Aucun périphérique compatible UPnP n'a été trouvé",
|
||||
"upnp_disabled": "UPnP désactivé avec succès",
|
||||
"upnp_enabled": "UPnP activé avec succès",
|
||||
"upnp_port_open_failed": "Impossible d'ouvrir les ports avec UPnP",
|
||||
"user_created": "Utilisateur créé avec succès",
|
||||
"user_creation_failed": "Impossible de créer l'utilisateur",
|
||||
"user_deleted": "Utilisateur supprimé avec succès",
|
||||
"user_deletion_failed": "Impossible de supprimer l'utilisateur",
|
||||
"user_home_creation_failed": "Impossible de créer le dossier personnel de l'utilisateur",
|
||||
"user_info_failed": "Impossible de récupérer les informations de l'utilisateur",
|
||||
"user_unknown": "Utilisateur inconnu",
|
||||
"user_update_failed": "Impossible de modifier l'utilisateur",
|
||||
"user_updated": "Utilisateur modifié avec succès",
|
||||
"yunohost_already_installed": "YunoHost est déjà installé",
|
||||
"yunohost_ca_creation_failed": "Impossible de créer l'autorité de certification",
|
||||
"yunohost_configured": "YunoHost configuré avec succès",
|
||||
"yunohost_installing": "Installation de YunoHost...",
|
||||
"action_invalid": "Action « {action:s} » incorrecte",
|
||||
"admin_password": "Mot de passe d'administration",
|
||||
"admin_password_change_failed": "Impossible de modifier le mot de passe d'administration",
|
||||
"admin_password_changed": "Mot de passe d'administration modifié avec succès",
|
||||
"app_already_installed": "{app:s} est déjà installé",
|
||||
"app_argument_choice_invalid": "Choix invalide pour le paramètre « {name:s} », il doit être l'un de {choices:s}",
|
||||
"app_argument_invalid": "Valeur invalide pour le paramètre « {name:s} » : {error:s}",
|
||||
"app_argument_missing": "Paramètre manquant « {:s} »",
|
||||
"app_argument_required": "Le paramètre « {name:s} » est requis",
|
||||
"app_extraction_failed": "Impossible d'extraire les fichiers d'installation",
|
||||
"app_id_invalid": "Id d'application incorrect",
|
||||
"app_install_files_invalid": "Fichiers d'installation incorrects",
|
||||
"app_location_already_used": "Une application est déjà installée à cet emplacement",
|
||||
"app_location_install_failed": "Impossible d'installer l'application à cet emplacement",
|
||||
"app_manifest_invalid": "Manifeste d'application incorrect",
|
||||
"app_no_upgrade": "Aucune application à mettre à jour",
|
||||
"app_not_correctly_installed": "{app:s} semble être mal installé",
|
||||
"app_not_installed": "{app:s} n'est pas installé",
|
||||
"app_not_properly_removed": "{app:s} n'a pas été supprimé correctement",
|
||||
"app_recent_version_required": "{app:s} nécessite une version plus récente de YunoHost",
|
||||
"app_removed": "{app:s} supprimé avec succès",
|
||||
"app_requirements_checking": "Vérification des paquets requis...",
|
||||
"app_requirements_failed": "Impossible de satisfaire les pré-requis : {error}",
|
||||
"app_requirements_unmeet": "Les pré-requis ne sont pas satisfaits, le paquet {pkgname} ({version}) doit être {spec}",
|
||||
"app_sources_fetch_failed": "Impossible de récupérer les fichiers sources",
|
||||
"app_unknown": "Application inconnue",
|
||||
"app_unsupported_remote_type": "Le type distant utilisé par l'application n'est pas supporté",
|
||||
"app_upgrade_failed": "Impossible de mettre à jour {app:s}",
|
||||
"app_upgraded": "{app:s} mis à jour avec succès",
|
||||
"appslist_fetched": "Liste d'applications récupérée avec succès",
|
||||
"appslist_removed": "Liste d'applications supprimée avec succès",
|
||||
"appslist_retrieve_error": "Impossible de récupérer la liste d'applications distante",
|
||||
"appslist_unknown": "Liste d'applications inconnue",
|
||||
"ask_current_admin_password": "Mot de passe d'administration actuel",
|
||||
"ask_email": "Adresse courriel",
|
||||
"ask_firstname": "Prénom",
|
||||
"ask_lastname": "Nom",
|
||||
"ask_list_to_remove": "Liste à supprimer",
|
||||
"ask_main_domain": "Domaine principal",
|
||||
"ask_new_admin_password": "Nouveau mot de passe d'administration",
|
||||
"ask_password": "Mot de passe",
|
||||
"backup_action_required": "Vous devez préciser ce qui est à sauvegarder",
|
||||
"backup_app_failed": "Impossible de sauvegarder l'application « {app:s} »",
|
||||
"backup_archive_app_not_found": "L'application « {app:s} » n'a pas été trouvée dans l'archive de la sauvegarde",
|
||||
"backup_archive_hook_not_exec": "Le script « {hook:s} » n'a pas été exécuté dans cette sauvegarde",
|
||||
"backup_archive_name_exists": "Une archive de sauvegarde avec ce nom existe déjà",
|
||||
"backup_archive_name_unknown": "L'archive locale de sauvegarde nommée « {name:s} » est inconnue",
|
||||
"backup_archive_open_failed": "Impossible d'ouvrir l'archive de sauvegarde",
|
||||
"backup_cleaning_failed": "Impossible de nettoyer le dossier temporaire de sauvegarde",
|
||||
"backup_complete": "Sauvegarde terminée",
|
||||
"backup_creating_archive": "Création de l'archive de sauvegarde...",
|
||||
"backup_delete_error": "Impossible de supprimer « {path:s} »",
|
||||
"backup_deleted": "La sauvegarde a bien été supprimée",
|
||||
"backup_extracting_archive": "Extraction de l'archive de sauvegarde...",
|
||||
"backup_hook_unknown": "Script de sauvegarde « {hook:s} » inconnu",
|
||||
"backup_invalid_archive": "Archive de sauvegarde incorrecte",
|
||||
"backup_nothings_done": "Il n'y a rien à sauvegarder",
|
||||
"backup_output_directory_forbidden": "Dossier de sortie interdit. Les sauvegardes ne peuvent être créées dans les dossiers /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ou /home/yunohost.backup/archives.",
|
||||
"backup_output_directory_not_empty": "Le dossier de sortie n'est pas vide",
|
||||
"backup_output_directory_required": "Vous devez spécifier un dossier de sortie pour la sauvegarde",
|
||||
"backup_running_app_script": "Lancement du script de sauvegarde de l'application « {app:s} »...",
|
||||
"backup_running_hooks": "Exécution des scripts de sauvegarde...",
|
||||
"custom_app_url_required": "Vous devez spécifier une URL pour mettre à jour votre application locale {app:s}",
|
||||
"custom_appslist_name_required": "Vous devez spécifier un nom pour votre liste d'applications personnalisée",
|
||||
"diagnostic_debian_version_error": "Impossible de déterminer la version de Debian : {error}",
|
||||
"diagnostic_kernel_version_error": "Impossible de récupérer la version du noyau : {error}",
|
||||
"diagnostic_monitor_disk_error": "Impossible de superviser les disques : {error}",
|
||||
"diagnostic_monitor_network_error": "Impossible de superviser le réseau : {error}",
|
||||
"diagnostic_monitor_system_error": "Impossible de superviser le système : {error}",
|
||||
"diagnostic_no_apps": "Aucune application installée",
|
||||
"dnsmasq_isnt_installed": "dnsmasq ne semble pas être installé, veuillez lancer « apt-get remove bind9 && apt-get install dnsmasq »",
|
||||
"domain_cert_gen_failed": "Impossible de générer le certificat",
|
||||
"domain_created": "Domaine créé avec succès",
|
||||
"domain_creation_failed": "Impossible de créer le domaine",
|
||||
"domain_deleted": "Domaine supprimé avec succès",
|
||||
"domain_deletion_failed": "Impossible de supprimer le domaine",
|
||||
"domain_dyndns_already_subscribed": "Vous avez déjà souscris à un domaine DynDNS",
|
||||
"domain_dyndns_invalid": "Domaine incorrect pour un usage avec DynDNS",
|
||||
"domain_dyndns_root_unknown": "Domaine DynDNS principal inconnu",
|
||||
"domain_exists": "Le domaine existe déjà",
|
||||
"domain_uninstall_app_first": "Une ou plusieurs applications sont installées sur ce domaine. Veuillez d'abord les désinstaller avant de supprimer ce domaine.",
|
||||
"domain_unknown": "Domaine inconnu",
|
||||
"domain_zone_exists": "Le fichier de zone DNS existe déjà",
|
||||
"domain_zone_not_found": "Fichier de zone DNS introuvable pour le domaine {:s}",
|
||||
"done": "Terminé.",
|
||||
"downloading": "Téléchargement...",
|
||||
"dyndns_cron_installed": "Tâche cron pour DynDNS installée avec succès",
|
||||
"dyndns_cron_remove_failed": "Impossible d'enlever la tâche cron pour DynDNS",
|
||||
"dyndns_cron_removed": "La tâche cron pour DynDNS a été enlevée avec succès",
|
||||
"dyndns_ip_update_failed": "Impossible de mettre à jour l'adresse IP sur le domaine DynDNS",
|
||||
"dyndns_ip_updated": "Adresse IP mise à jour avec succès sur le domaine DynDNS",
|
||||
"dyndns_key_generating": "La clé DNS est en cours de génération, cela peut prendre du temps...",
|
||||
"dyndns_key_not_found": "Clé DNS introuvable pour le domaine",
|
||||
"dyndns_no_domain_registered": "Aucun domaine n'a été enregistré avec DynDNS",
|
||||
"dyndns_registered": "Domaine DynDNS enregistré avec succès",
|
||||
"dyndns_registration_failed": "Impossible d'enregistrer le domaine DynDNS : {error:s}",
|
||||
"dyndns_unavailable": "Sous-domaine DynDNS indisponible",
|
||||
"executing_command": "Exécution de la commande « {command:s} »...",
|
||||
"executing_script": "Exécution du script « {script:s} »...",
|
||||
"extracting": "Extraction...",
|
||||
"field_invalid": "Champ incorrect : « {:s} »",
|
||||
"firewall_reload_failed": "Impossible de recharger le pare-feu",
|
||||
"firewall_reloaded": "Pare-feu rechargé avec succès",
|
||||
"firewall_rules_cmd_failed": "Certaines règles du pare-feu n'ont pas pu être appliquées. Pour plus d'informations, consultez le journal.",
|
||||
"format_datetime_short": "%d/%m/%Y %H:%M",
|
||||
"hook_argument_missing": "Argument manquant : '{:s}'",
|
||||
"hook_choice_invalid": "Choix incorrect : '{:s}'",
|
||||
"hook_exec_failed": "Échec de l'exécution du script « {path:s} »",
|
||||
"hook_exec_not_terminated": "L'exécution du script « {path:s} » ne s'est pas terminée",
|
||||
"hook_list_by_invalid": "Propriété pour lister les scripts incorrecte",
|
||||
"hook_name_unknown": "Nom de script « {name:s} » inconnu",
|
||||
"installation_complete": "Installation terminée",
|
||||
"installation_failed": "Échec de l'installation",
|
||||
"ip6tables_unavailable": "Vous ne pouvez pas jouer avec ip6tables ici. Vous êtes sûrement dans un conteneur, ou alors votre noyau ne le supporte pas.",
|
||||
"iptables_unavailable": "Vous ne pouvez pas jouer avec iptables ici. Vous êtes sûrement dans un conteneur, autrement votre noyau ne le supporte pas.",
|
||||
"ldap_initialized": "Répertoire LDAP initialisé avec succès",
|
||||
"license_undefined": "indéfinie",
|
||||
"mail_alias_remove_failed": "Impossible de supprimer l'adresse mail supplémentaire « {mail:s} »",
|
||||
"mail_domain_unknown": "Domaine « {domain:s} » de l'adresse mail inconnu",
|
||||
"mail_forward_remove_failed": "Impossible de supprimer l'adresse courriel de transfert « {mail:s} »",
|
||||
"maindomain_change_failed": "Impossible de modifier le domaine principal",
|
||||
"maindomain_changed": "Domaine principal modifié avec succès",
|
||||
"monitor_disabled": "Le suivi de l'état du serveur a été désactivé avec succès",
|
||||
"monitor_enabled": "Suivi de l'état du serveur activé avec succès",
|
||||
"monitor_glances_con_failed": "Impossible de se connecter au serveur Glances",
|
||||
"monitor_not_enabled": "Le suivi de l'état du serveur n'est pas activé",
|
||||
"monitor_period_invalid": "Période de temps incorrecte",
|
||||
"monitor_stats_file_not_found": "Le fichier de statistiques est introuvable",
|
||||
"monitor_stats_no_update": "Aucune donnée de l'état du serveur à mettre à jour",
|
||||
"monitor_stats_period_unavailable": "Aucune statistique n'est disponible pour la période",
|
||||
"mountpoint_unknown": "Point de montage inconnu",
|
||||
"mysql_db_creation_failed": "Impossible de créer la base de données MySQL",
|
||||
"mysql_db_init_failed": "Impossible d'initialiser la base de données MySQL",
|
||||
"mysql_db_initialized": "Base de donnée MySQL initialisée avec succès",
|
||||
"network_check_mx_ko": "L'enregistrement DNS MX n'est pas précisé",
|
||||
"network_check_smtp_ko": "Le trafic mail sortant (port 25 SMTP) semble bloqué par votre réseau",
|
||||
"network_check_smtp_ok": "Le trafic courriel sortant (port 25 SMTP) n'est pas bloqué",
|
||||
"new_domain_required": "Vous devez spécifier le nouveau domaine principal",
|
||||
"no_appslist_found": "Aucune liste d'applications trouvée",
|
||||
"no_internet_connection": "Le serveur n'est pas connecté à internet",
|
||||
"no_ipv6_connectivity": "La connectivité IPv6 n'est pas disponible",
|
||||
"no_restore_script": "Le script de sauvegarde n'a pas été trouvé pour l'application « {app:s} »",
|
||||
"no_such_conf_file": "Le fichier {file:s} n’existe pas, il ne peut pas être copié",
|
||||
"not_enough_disk_space": "L'espace disque est insuffisant sur « {path:s} »",
|
||||
"package_not_installed": "Le paquet « {pkgname} » n'est pas installé",
|
||||
"package_unexpected_error": "Une erreur inattendue est survenue avec le paquet « {pkgname} »",
|
||||
"package_unknown": "Paquet « {pkgname} » inconnu",
|
||||
"packages_no_upgrade": "Il n'y a aucun paquet à mettre à jour",
|
||||
"packages_upgrade_critical_later": "Les paquets critiques ({packages:s}) seront mis à jour ultérieurement",
|
||||
"packages_upgrade_failed": "Impossible de mettre à jour tous les paquets",
|
||||
"path_removal_failed": "Impossible de supprimer le chemin {:s}",
|
||||
"pattern_backup_archive_name": "Doit être un nom de fichier valide composé de caractères alphanumérique et -_. uniquement",
|
||||
"pattern_domain": "Doit être un nom de domaine valide (ex : mon-domaine.org)",
|
||||
"pattern_email": "Doit être une adresse courriel valide (ex. : someone@domain.org)",
|
||||
"pattern_firstname": "Doit être un prénom valide",
|
||||
"pattern_lastname": "Doit être un nom valide",
|
||||
"pattern_listname": "Doit être composé uniquement de caractères alphanumériques et de tirets bas",
|
||||
"pattern_mailbox_quota": "Doit être une taille avec le suffixe b/k/M/G/T ou 0 pour désactiver le quota",
|
||||
"pattern_password": "Doit être composé d'au moins 3 caractères",
|
||||
"pattern_port": "Doit être un numéro de port valide (ex. : 0-65535)",
|
||||
"pattern_port_or_range": "Doit être un numéro de port valide (ex. : 0-65535) ou une gamme de ports (ex. : 100:200)",
|
||||
"pattern_positive_number": "Doit être un nombre positif",
|
||||
"pattern_username": "Doit être composé uniquement de caractères alphanumériques minuscules et de tirets bas",
|
||||
"port_already_closed": "Le port {port:d} est déjà fermé pour les connexions {ip_version:s}",
|
||||
"port_already_opened": "Le port {port:d} est déjà ouvert pour les connexions {ip_version:s}",
|
||||
"port_available": "Le port {port:d} est disponible",
|
||||
"port_unavailable": "Le port {port:d} n'est pas disponible",
|
||||
"restore_action_required": "Vous devez préciser ce qui est à restaurer",
|
||||
"restore_already_installed_app": "Une application est déjà installée avec l'id « {app:s} »",
|
||||
"restore_app_failed": "Impossible de restaurer l'application « {app:s} »",
|
||||
"restore_cleaning_failed": "Impossible de nettoyer le dossier temporaire de restauration",
|
||||
"restore_complete": "Restauration terminée",
|
||||
"restore_confirm_yunohost_installed": "Voulez-vous vraiment restaurer un système déjà installé ? [{answers:s}]",
|
||||
"restore_failed": "Impossible de restaurer le système",
|
||||
"restore_hook_unavailable": "Le script de restauration « {hook:s} » n'est pas disponible sur votre système",
|
||||
"restore_nothings_done": "Rien n'a été restauré",
|
||||
"restore_running_app_script": "Lancement du script de restauration pour l'application « {app:s} »...",
|
||||
"restore_running_hooks": "Exécution des scripts de restauration...",
|
||||
"service_add_configuration": "Ajout du fichier de configuration {file:s}",
|
||||
"service_add_failed": "Impossible d'ajouter le service « {service:s} »",
|
||||
"service_added": "Service « {service:s} » ajouté avec succès",
|
||||
"service_already_started": "Le service « {service:s} » est déjà démarré",
|
||||
"service_already_stopped": "Le service « {service:s} » est déjà arrêté",
|
||||
"service_cmd_exec_failed": "Impossible d'exécuter la commande « {command:s} »",
|
||||
"service_configuration_conflict": "Le fichier {file:s} a été modifié depuis sa dernière génération. Veuillez y appliquer les modifications manuellement ou utiliser l’option --force (ce qui écrasera toutes les modifications effectuées sur le fichier).",
|
||||
"service_configured": "La configuration du service « {service:s} » a été générée avec succès",
|
||||
"service_configured_all": "La configuration de tous les services a été générée avec succès",
|
||||
"service_disable_failed": "Impossible de désactiver le service « {service:s} »",
|
||||
"service_disabled": "Service « {service:s} » désactivé avec succès",
|
||||
"service_enable_failed": "Impossible d'activer le service « {service:s} »",
|
||||
"service_enabled": "Service « {service:s} » activé avec succès",
|
||||
"service_no_log": "Aucun journal à afficher pour le service « {service:s} »",
|
||||
"service_remove_failed": "Impossible d'enlever le service « {service:s} »",
|
||||
"service_removed": "Service « {service:s} » enlevé avec succès",
|
||||
"service_start_failed": "Impossible de démarrer le service « {service:s} »",
|
||||
"service_started": "Le service « {service:s} » a démarré avec succès",
|
||||
"service_status_failed": "Impossible de déterminer le statut du service « {service:s} »",
|
||||
"service_stop_failed": "Impossible d'arrêter le service « {service:s} »",
|
||||
"service_stopped": "Service « {service:s} » arrêté avec succès",
|
||||
"service_unknown": "Service « {service:s} » inconnu",
|
||||
"services_configured": "La configuration a été générée avec succès",
|
||||
"show_diff": "Voici les différences :\n{diff:s}",
|
||||
"ssowat_conf_generated": "Configuration de SSOwat générée avec succès",
|
||||
"ssowat_conf_updated": "La configuration persistante de SSOwat a été mise à jour avec succès",
|
||||
"system_upgraded": "Système mis à jour avec succès",
|
||||
"system_username_exists": "Le nom d'utilisateur existe déjà dans les utilisateurs système",
|
||||
"unbackup_app": "L'application « {app:s} » ne sera pas sauvegardée",
|
||||
"unexpected_error": "Une erreur inattendue est survenue",
|
||||
"unit_unknown": "Unité « {unit:s} » inconnue",
|
||||
"unlimit": "Pas de quota",
|
||||
"unrestore_app": "L'application « {app:s} » ne sera pas restaurée",
|
||||
"update_cache_failed": "Impossible de mettre à jour le cache de l'APT",
|
||||
"updating_apt_cache": "Mise à jour de la liste des paquets disponibles...",
|
||||
"upgrade_complete": "Mise à jour terminée",
|
||||
"upgrading_packages": "Mise à jour des paquets...",
|
||||
"upnp_dev_not_found": "Aucun périphérique compatible UPnP n'a été trouvé",
|
||||
"upnp_disabled": "UPnP désactivé avec succès",
|
||||
"upnp_enabled": "UPnP activé avec succès",
|
||||
"upnp_port_open_failed": "Impossible d'ouvrir les ports avec UPnP",
|
||||
"user_created": "Utilisateur créé avec succès",
|
||||
"user_creation_failed": "Impossible de créer l'utilisateur",
|
||||
"user_deleted": "Utilisateur supprimé avec succès",
|
||||
"user_deletion_failed": "Impossible de supprimer l'utilisateur",
|
||||
"user_home_creation_failed": "Impossible de créer le dossier personnel de l'utilisateur",
|
||||
"user_info_failed": "Impossible de récupérer les informations de l'utilisateur",
|
||||
"user_unknown": "Utilisateur « {user:s} » inconnu",
|
||||
"user_update_failed": "Impossible de modifier l'utilisateur",
|
||||
"user_updated": "Utilisateur modifié avec succès",
|
||||
"yunohost_already_installed": "YunoHost est déjà installé",
|
||||
"yunohost_ca_creation_failed": "Impossible de créer l'autorité de certification",
|
||||
"yunohost_configured": "YunoHost configuré avec succès",
|
||||
"yunohost_installing": "Installation de YunoHost...",
|
||||
"yunohost_not_installed": "YunoHost n'est pas ou pas correctement installé. Veuillez exécuter « yunohost tools postinstall »."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
{
|
||||
"app_already_installed": "{:s} è già installato",
|
||||
"app_extraction_failed": "Impossibile estrarre i file di installazione",
|
||||
"app_not_installed": "{:s} non è installato",
|
||||
"app_unknown": "Applicazione sconosciuta",
|
||||
"ask_email": "Indirizzo email",
|
||||
"ask_password": "Password",
|
||||
"backup_archive_name_exists": "Il nome dell'archivio del backup esiste già",
|
||||
"backup_complete": "Backup completo",
|
||||
"backup_invalid_archive": "Archivio di backup non valido",
|
||||
"backup_output_directory_not_empty": "Directory di output non è vuota",
|
||||
"backup_running_app_script": "Esecuzione script di backup dell'applicazione '{:s}'...",
|
||||
"domain_created": "Dominio creato con successo",
|
||||
"domain_dyndns_invalid": "Dominio non valido da utilizzare con DynDNS",
|
||||
"domain_exists": "Dominio esiste già",
|
||||
"ldap_initialized": "LDAP inizializzato con successo",
|
||||
"pattern_email": "Deve essere un indirizzo e-mail valido (es someone@domain.org)",
|
||||
"pattern_mailbox_quota": "Deve essere una dimensione con un suffisso b/k/M/G/T o 0 per disabilitare la quota",
|
||||
"port_already_opened": "Port {} è già aperto per {:s} connessioni",
|
||||
"port_unavailable": "Porta {} non è disponibile",
|
||||
"service_add_failed": "Impossibile aggiungere servizio '{:s}'",
|
||||
"service_cmd_exec_failed": "Impossibile eseguire il comando '{:s}'",
|
||||
"service_disabled": "Servizio '{:s}' disattivato con successo",
|
||||
"service_remove_failed": "Impossibile rimuovere il servizio '{:s}'",
|
||||
"service_removed": "Servizio rimosso con successo",
|
||||
"service_stop_failed": "Impossibile arrestare il servizio '{:s}'",
|
||||
"system_username_exists": "Nome utente esiste già negli utenti del sistema",
|
||||
"unrestore_app": "Applicazione '{app:s}' non verrà ripristinato",
|
||||
"upgrading_packages": "Aggiornamento dei pacchetti...",
|
||||
"app_already_installed": "{app:s} è già installato",
|
||||
"app_extraction_failed": "Impossibile estrarre i file di installazione",
|
||||
"app_not_installed": "{app:s} non è installato",
|
||||
"app_unknown": "Applicazione sconosciuta",
|
||||
"ask_email": "Indirizzo email",
|
||||
"ask_password": "Password",
|
||||
"backup_archive_name_exists": "Il nome dell'archivio del backup esiste già",
|
||||
"backup_complete": "Backup completo",
|
||||
"backup_invalid_archive": "Archivio di backup non valido",
|
||||
"backup_output_directory_not_empty": "Directory di output non è vuota",
|
||||
"backup_running_app_script": "Esecuzione script di backup dell'applicazione '{app:s}'...",
|
||||
"domain_created": "Dominio creato con successo",
|
||||
"domain_dyndns_invalid": "Dominio non valido da utilizzare con DynDNS",
|
||||
"domain_exists": "Dominio esiste già",
|
||||
"ldap_initialized": "LDAP inizializzato con successo",
|
||||
"pattern_email": "Deve essere un indirizzo e-mail valido (es someone@domain.org)",
|
||||
"pattern_mailbox_quota": "Deve essere una dimensione con un suffisso b/k/M/G/T o 0 per disabilitare la quota",
|
||||
"port_already_opened": "Port {port:d} è già aperto per {ip_version:s} connessioni",
|
||||
"port_unavailable": "Porta {port:d} non è disponibile",
|
||||
"service_add_failed": "Impossibile aggiungere servizio '{service:s}'",
|
||||
"service_cmd_exec_failed": "Impossibile eseguire il comando '{command:s}'",
|
||||
"service_disabled": "Servizio '{service:s}' disattivato con successo",
|
||||
"service_remove_failed": "Impossibile rimuovere il servizio '{service:s}'",
|
||||
"service_removed": "Servizio rimosso con successo",
|
||||
"service_stop_failed": "Impossibile arrestare il servizio '{service:s}'",
|
||||
"system_username_exists": "Nome utente esiste già negli utenti del sistema",
|
||||
"unrestore_app": "Applicazione '{app:s}' non verrà ripristinato",
|
||||
"upgrading_packages": "Aggiornamento dei pacchetti...",
|
||||
"user_deleted": "Utente cancellato con successo"
|
||||
}
|
||||
}
|
||||
|
|
214
locales/nl.json
214
locales/nl.json
|
@ -1,109 +1,109 @@
|
|||
{
|
||||
"action_invalid": "Ongeldige actie '{:s}'",
|
||||
"admin_password": "Administration password",
|
||||
"admin_password_changed": "Het admin-wachtwoord is gewijzigd",
|
||||
"app_already_installed": "{:s} is al geïnstalleerd",
|
||||
"app_argument_invalid": "'{name:s}' bevat geldige waarde: {error:s}",
|
||||
"app_argument_required": "Het '{name:s}' moet ingevuld worden",
|
||||
"app_extraction_failed": "Kan installatiebestanden niet uitpakken",
|
||||
"app_id_invalid": "Ongeldige app-id",
|
||||
"app_install_files_invalid": "Ongeldige installatiebestanden",
|
||||
"app_location_already_used": "Er is al een app geïnstalleerd op deze locatie",
|
||||
"app_location_install_failed": "Kan app niet installeren op deze locatie",
|
||||
"app_manifest_invalid": "Ongeldig app-manifest",
|
||||
"app_no_upgrade": "Geen apps op te upgraden",
|
||||
"app_not_installed": "{:s} is niet geinstalleerd ",
|
||||
"app_recent_version_required": "{:s} vereist een nieuwere versie van moulinette",
|
||||
"app_removed": "{:s} succesvol verwijderd",
|
||||
"app_sources_fetch_failed": "Kan bronbestanden niet ophalen",
|
||||
"app_unknown": "Onbekende app",
|
||||
"app_upgrade_failed": "Kan niet alle apps updaten",
|
||||
"app_upgraded": "{:s} succesvol geüpgrade ",
|
||||
"appslist_fetched": "App-lijst succesvol aangemaakt.",
|
||||
"appslist_removed": "App-lijst succesvol verwijderd",
|
||||
"appslist_unknown": "Onbekende app-lijst",
|
||||
"ask_current_admin_password": "Huidig administratorwachtwoord",
|
||||
"ask_email": "Email-adres",
|
||||
"ask_firstname": "Voornaam",
|
||||
"ask_lastname": "Achternaam",
|
||||
"ask_new_admin_password": "Nieuw administratorwachtwoord",
|
||||
"ask_password": "Wachtwoord",
|
||||
"backup_archive_name_exists": "Backuparchief bestaat al",
|
||||
"backup_cleaning_failed": "Kan tijdelijke backup directory niet leeg maken",
|
||||
"backup_creating_archive": "Backup wordt gestart...",
|
||||
"backup_invalid_archive": "Ongeldig backup archief",
|
||||
"backup_output_directory_not_empty": "Doelmap is niet leeg",
|
||||
"backup_running_app_script": "Backup script voor app '{app:s}' is gestart...",
|
||||
"custom_app_url_required": "U moet een URL opgeven om uw aangepaste app {:s} bij te werken",
|
||||
"custom_appslist_name_required": "U moet een naam opgeven voor uw aangepaste app-lijst",
|
||||
"dnsmasq_isnt_installed": "dnsmasq lijkt niet geïnstalleerd te zijn, voer alstublieft het volgende commando uit: 'apt-get remove bind9 && apt-get install dnsmasq'",
|
||||
"domain_cert_gen_failed": "Kan certificaat niet genereren",
|
||||
"domain_created": "Domein succesvol aangemaakt",
|
||||
"domain_creation_failed": "Kan domein niet aanmaken",
|
||||
"domain_deleted": "Domein succesvol verwijderd",
|
||||
"domain_deletion_failed": "Kan domein niet verwijderen",
|
||||
"domain_dyndns_already_subscribed": "Dit domein is al geregistreed bij DynDNS",
|
||||
"domain_dyndns_invalid": "Het domein is ongeldig voor DynDNS",
|
||||
"domain_dyndns_root_unknown": "Onbekend DynDNS root domein",
|
||||
"domain_exists": "Domein bestaat al",
|
||||
"domain_uninstall_app_first": "Een of meerdere apps zijn geïnstalleerd op dit domein, verwijder deze voordat u het domein verwijderd.",
|
||||
"domain_unknown": "Onbekend domein",
|
||||
"domain_zone_exists": "DNS zone bestand bestaat al",
|
||||
"domain_zone_not_found": "DNS zone bestand niet gevonden voor domein: {:s}",
|
||||
"done": "Voltooid.",
|
||||
"downloading": "Downloaden...",
|
||||
"dyndns_cron_remove_failed": "De cron-job voor DynDNS kon niet worden verwijderd",
|
||||
"dyndns_ip_update_failed": "Kan het IP adres niet updaten bij DynDNS",
|
||||
"dyndns_ip_updated": "IP adres is aangepast bij DynDNS",
|
||||
"dyndns_key_generating": "DNS sleutel word aangemaakt, wacht een moment...",
|
||||
"dyndns_unavailable": "DynDNS subdomein is niet beschikbaar",
|
||||
"executing_script": "Script uitvoeren...",
|
||||
"extracting": "Uitpakken...",
|
||||
"installation_complete": "Installatie voltooid",
|
||||
"installation_failed": "Installatie gefaald",
|
||||
"ldap_initialized": "LDAP staat klaar voor gebruik",
|
||||
"license_undefined": "undefined",
|
||||
"mail_alias_remove_failed": "Kan mail alias niet verwijderen '{:s}'",
|
||||
"monitor_stats_no_update": "Er zijn geen recente monitoringstatistieken bij te werken",
|
||||
"mysql_db_creation_failed": "Aanmaken MySQL database gefaald",
|
||||
"mysql_db_init_failed": "Initialiseren MySQL database gefaald",
|
||||
"mysql_db_initialized": "MySQL database succesvol geïnitialiseerd",
|
||||
"network_check_smtp_ko": "Uitgaande mail (SMPT port 25) wordt blijkbaar geblokkeerd door uw het netwerk",
|
||||
"no_appslist_found": "Geen app-lijsten gevonden",
|
||||
"no_internet_connection": "Server is niet verbonden met het internet",
|
||||
"no_ipv6_connectivity": "IPv6-stack is onbeschikbaar",
|
||||
"path_removal_failed": "Kan pad niet verwijderen {:s}",
|
||||
"pattern_email": "Moet een geldig emailadres bevatten (bv. abc@example.org)",
|
||||
"pattern_listname": "Slechts cijfers, letters en '_' zijn toegelaten",
|
||||
"pattern_mailbox_quota": "Mailbox quota moet een waarde bevatten met b/k/M/G/T erachter of 0 om geen quota in te stellen",
|
||||
"pattern_password": "Wachtwoord moet tenminste 3 karakters lang zijn",
|
||||
"port_already_closed": "Poort {} is al gesloten voor {:s} verbindingen",
|
||||
"port_already_opened": "Poort {} is al open voor {:s} verbindingen",
|
||||
"port_available": "Poort {} is beschikbaar",
|
||||
"port_unavailable": "Poort {} is niet beschikbaar",
|
||||
"restore_app_failed": "De app '{app:s}' kon niet worden terug gezet",
|
||||
"restore_hook_unavailable": "De restauration hook '{hook:s}' is niet beschikbaar op dit systeem",
|
||||
"service_add_failed": "Kan service '{:s}' niet toevoegen",
|
||||
"service_already_started": "Service '{:s}' draait al",
|
||||
"service_cmd_exec_failed": "Kan '{:s}' niet uitvoeren",
|
||||
"service_disabled": "Service '{:s}' is uitgeschakeld",
|
||||
"service_remove_failed": "Kan service '{:s}' niet verwijderen",
|
||||
"service_removed": "Service werd verwijderd",
|
||||
"service_stop_failed": "Kan service '{:s}' niet stoppen",
|
||||
"service_unknown": "De service '{:s}' bestaat niet",
|
||||
"show_diff": "Let op de volgende verschillen zijn:\n{diff:s}",
|
||||
"unexpected_error": "Er is een onbekende fout opgetreden",
|
||||
"unrestore_app": "App '{app:s}' wordt niet teruggezet",
|
||||
"updating_apt_cache": "Lijst van beschikbare pakketen wordt bijgewerkt",
|
||||
"upgrade_complete": "Upgrade voltooid",
|
||||
"upgrading_packages": "Pakketten worden geüpdate...",
|
||||
"upnp_dev_not_found": "Geen UPnP apparaten gevonden",
|
||||
"upnp_disabled": "UPnP successvol uitgeschakeld",
|
||||
"upnp_enabled": "UPnP succesvol ingeschakeld",
|
||||
"upnp_port_open_failed": "Kan UPnP poorten niet openen",
|
||||
"user_deleted": "Gebruiker werd verwijderd",
|
||||
"user_home_creation_failed": "Kan de map voor deze gebruiker niet aanmaken",
|
||||
"user_unknown": "Gebruikersnaam is onbekend",
|
||||
"user_update_failed": "Kan gebruiker niet bijwerken",
|
||||
"action_invalid": "Ongeldige actie '{action:s}'",
|
||||
"admin_password": "Administration password",
|
||||
"admin_password_changed": "Het admin-wachtwoord is gewijzigd",
|
||||
"app_already_installed": "{app:s} is al geïnstalleerd",
|
||||
"app_argument_invalid": "'{name:s}' bevat geldige waarde: {error:s}",
|
||||
"app_argument_required": "Het '{name:s}' moet ingevuld worden",
|
||||
"app_extraction_failed": "Kan installatiebestanden niet uitpakken",
|
||||
"app_id_invalid": "Ongeldige app-id",
|
||||
"app_install_files_invalid": "Ongeldige installatiebestanden",
|
||||
"app_location_already_used": "Er is al een app geïnstalleerd op deze locatie",
|
||||
"app_location_install_failed": "Kan app niet installeren op deze locatie",
|
||||
"app_manifest_invalid": "Ongeldig app-manifest",
|
||||
"app_no_upgrade": "Geen apps op te upgraden",
|
||||
"app_not_installed": "{app:s} is niet geinstalleerd",
|
||||
"app_recent_version_required": "{:s} vereist een nieuwere versie van moulinette",
|
||||
"app_removed": "{app:s} succesvol verwijderd",
|
||||
"app_sources_fetch_failed": "Kan bronbestanden niet ophalen",
|
||||
"app_unknown": "Onbekende app",
|
||||
"app_upgrade_failed": "Kan niet alle apps updaten",
|
||||
"app_upgraded": "{app:s} succesvol geüpgrade",
|
||||
"appslist_fetched": "App-lijst succesvol aangemaakt.",
|
||||
"appslist_removed": "App-lijst succesvol verwijderd",
|
||||
"appslist_unknown": "Onbekende app-lijst",
|
||||
"ask_current_admin_password": "Huidig administratorwachtwoord",
|
||||
"ask_email": "Email-adres",
|
||||
"ask_firstname": "Voornaam",
|
||||
"ask_lastname": "Achternaam",
|
||||
"ask_new_admin_password": "Nieuw administratorwachtwoord",
|
||||
"ask_password": "Wachtwoord",
|
||||
"backup_archive_name_exists": "Backuparchief bestaat al",
|
||||
"backup_cleaning_failed": "Kan tijdelijke backup directory niet leeg maken",
|
||||
"backup_creating_archive": "Backup wordt gestart...",
|
||||
"backup_invalid_archive": "Ongeldig backup archief",
|
||||
"backup_output_directory_not_empty": "Doelmap is niet leeg",
|
||||
"backup_running_app_script": "Backup script voor app '{app:s}' is gestart...",
|
||||
"custom_app_url_required": "U moet een URL opgeven om uw aangepaste app {app:s} bij te werken",
|
||||
"custom_appslist_name_required": "U moet een naam opgeven voor uw aangepaste app-lijst",
|
||||
"dnsmasq_isnt_installed": "dnsmasq lijkt niet geïnstalleerd te zijn, voer alstublieft het volgende commando uit: 'apt-get remove bind9 && apt-get install dnsmasq'",
|
||||
"domain_cert_gen_failed": "Kan certificaat niet genereren",
|
||||
"domain_created": "Domein succesvol aangemaakt",
|
||||
"domain_creation_failed": "Kan domein niet aanmaken",
|
||||
"domain_deleted": "Domein succesvol verwijderd",
|
||||
"domain_deletion_failed": "Kan domein niet verwijderen",
|
||||
"domain_dyndns_already_subscribed": "Dit domein is al geregistreed bij DynDNS",
|
||||
"domain_dyndns_invalid": "Het domein is ongeldig voor DynDNS",
|
||||
"domain_dyndns_root_unknown": "Onbekend DynDNS root domein",
|
||||
"domain_exists": "Domein bestaat al",
|
||||
"domain_uninstall_app_first": "Een of meerdere apps zijn geïnstalleerd op dit domein, verwijder deze voordat u het domein verwijderd.",
|
||||
"domain_unknown": "Onbekend domein",
|
||||
"domain_zone_exists": "DNS zone bestand bestaat al",
|
||||
"domain_zone_not_found": "DNS zone bestand niet gevonden voor domein: {:s}",
|
||||
"done": "Voltooid.",
|
||||
"downloading": "Downloaden...",
|
||||
"dyndns_cron_remove_failed": "De cron-job voor DynDNS kon niet worden verwijderd",
|
||||
"dyndns_ip_update_failed": "Kan het IP adres niet updaten bij DynDNS",
|
||||
"dyndns_ip_updated": "IP adres is aangepast bij DynDNS",
|
||||
"dyndns_key_generating": "DNS sleutel word aangemaakt, wacht een moment...",
|
||||
"dyndns_unavailable": "DynDNS subdomein is niet beschikbaar",
|
||||
"executing_script": "Script uitvoeren...",
|
||||
"extracting": "Uitpakken...",
|
||||
"installation_complete": "Installatie voltooid",
|
||||
"installation_failed": "Installatie gefaald",
|
||||
"ldap_initialized": "LDAP staat klaar voor gebruik",
|
||||
"license_undefined": "undefined",
|
||||
"mail_alias_remove_failed": "Kan mail alias niet verwijderen '{mail:s}'",
|
||||
"monitor_stats_no_update": "Er zijn geen recente monitoringstatistieken bij te werken",
|
||||
"mysql_db_creation_failed": "Aanmaken MySQL database gefaald",
|
||||
"mysql_db_init_failed": "Initialiseren MySQL database gefaald",
|
||||
"mysql_db_initialized": "MySQL database succesvol geïnitialiseerd",
|
||||
"network_check_smtp_ko": "Uitgaande mail (SMPT port 25) wordt blijkbaar geblokkeerd door uw het netwerk",
|
||||
"no_appslist_found": "Geen app-lijsten gevonden",
|
||||
"no_internet_connection": "Server is niet verbonden met het internet",
|
||||
"no_ipv6_connectivity": "IPv6-stack is onbeschikbaar",
|
||||
"path_removal_failed": "Kan pad niet verwijderen {:s}",
|
||||
"pattern_email": "Moet een geldig emailadres bevatten (bv. abc@example.org)",
|
||||
"pattern_listname": "Slechts cijfers, letters en '_' zijn toegelaten",
|
||||
"pattern_mailbox_quota": "Mailbox quota moet een waarde bevatten met b/k/M/G/T erachter of 0 om geen quota in te stellen",
|
||||
"pattern_password": "Wachtwoord moet tenminste 3 karakters lang zijn",
|
||||
"port_already_closed": "Poort {port:d} is al gesloten voor {ip_version:s} verbindingen",
|
||||
"port_already_opened": "Poort {port:d} is al open voor {ip_version:s} verbindingen",
|
||||
"port_available": "Poort {port:d} is beschikbaar",
|
||||
"port_unavailable": "Poort {port:d} is niet beschikbaar",
|
||||
"restore_app_failed": "De app '{app:s}' kon niet worden terug gezet",
|
||||
"restore_hook_unavailable": "De restauration hook '{hook:s}' is niet beschikbaar op dit systeem",
|
||||
"service_add_failed": "Kan service '{service:s}' niet toevoegen",
|
||||
"service_already_started": "Service '{service:s}' draait al",
|
||||
"service_cmd_exec_failed": "Kan '{command:s}' niet uitvoeren",
|
||||
"service_disabled": "Service '{service:s}' is uitgeschakeld",
|
||||
"service_remove_failed": "Kan service '{service:s}' niet verwijderen",
|
||||
"service_removed": "Service werd verwijderd",
|
||||
"service_stop_failed": "Kan service '{service:s}' niet stoppen",
|
||||
"service_unknown": "De service '{service:s}' bestaat niet",
|
||||
"show_diff": "Let op de volgende verschillen zijn:\n{diff:s}",
|
||||
"unexpected_error": "Er is een onbekende fout opgetreden",
|
||||
"unrestore_app": "App '{app:s}' wordt niet teruggezet",
|
||||
"updating_apt_cache": "Lijst van beschikbare pakketen wordt bijgewerkt",
|
||||
"upgrade_complete": "Upgrade voltooid",
|
||||
"upgrading_packages": "Pakketten worden geüpdate...",
|
||||
"upnp_dev_not_found": "Geen UPnP apparaten gevonden",
|
||||
"upnp_disabled": "UPnP successvol uitgeschakeld",
|
||||
"upnp_enabled": "UPnP succesvol ingeschakeld",
|
||||
"upnp_port_open_failed": "Kan UPnP poorten niet openen",
|
||||
"user_deleted": "Gebruiker werd verwijderd",
|
||||
"user_home_creation_failed": "Kan de map voor deze gebruiker niet aanmaken",
|
||||
"user_unknown": "Gebruikersnaam is onbekend",
|
||||
"user_update_failed": "Kan gebruiker niet bijwerken",
|
||||
"yunohost_configured": "YunoHost configuratie is OK"
|
||||
}
|
||||
}
|
||||
|
|
292
locales/pt.json
292
locales/pt.json
|
@ -1,148 +1,148 @@
|
|||
{
|
||||
"action_invalid": "Acção Inválida '{:s}'",
|
||||
"admin_password": "Senha de administração",
|
||||
"admin_password_change_failed": "Não foi possível alterar a senha",
|
||||
"admin_password_changed": "Senha de administração alterada com êxito",
|
||||
"app_already_installed": "{:s} já está instalada",
|
||||
"app_extraction_failed": "Não foi possível extrair os ficheiros para instalação",
|
||||
"app_id_invalid": "ID da aplicação invélida",
|
||||
"app_install_files_invalid": "Ficheiros para instalação corrompidos",
|
||||
"app_location_already_used": "Já existe uma aplicação instalada neste diretório",
|
||||
"app_location_install_failed": "Não foi possível instalar a aplicação neste diretório",
|
||||
"app_manifest_invalid": "Manifesto da aplicação inválido",
|
||||
"app_no_upgrade": "Não existem aplicações para atualizar",
|
||||
"app_not_installed": "{:s} não está instalada",
|
||||
"app_recent_version_required": "{:s} requer uma versão mais recente da moulinette",
|
||||
"app_removed": "{:s} removida com êxito",
|
||||
"app_sources_fetch_failed": "Impossível obter os códigos fontes",
|
||||
"app_unknown": "Aplicação desconhecida",
|
||||
"app_upgrade_failed": "Unable to upgrade all apps",
|
||||
"app_upgraded": "{:s} atualizada com êxito",
|
||||
"appslist_fetched": "Lista de aplicações processada com êxito",
|
||||
"appslist_removed": "Lista de aplicações removida com êxito",
|
||||
"appslist_retrieve_error": "Não foi possível obter a lista de aplicações remotas",
|
||||
"appslist_unknown": "Lista de aplicaçoes desconhecida",
|
||||
"ask_current_admin_password": "Senha de administração atual",
|
||||
"ask_email": "Correio eletrónico",
|
||||
"ask_firstname": "Primeiro nome",
|
||||
"ask_lastname": "Último nome",
|
||||
"ask_list_to_remove": "Lista para remover",
|
||||
"ask_main_domain": "Domínio principal",
|
||||
"ask_new_admin_password": "Senha de administração nova",
|
||||
"ask_password": "Senha",
|
||||
"backup_complete": "Backup completo",
|
||||
"backup_creating_archive": "A criar ficheiro de backup...",
|
||||
"backup_invalid_archive": "Arquivo de backup inválido",
|
||||
"backup_output_directory_not_empty": "A pasta de destino não se encontra vazia",
|
||||
"custom_app_url_required": "Deve proporcionar uma URL para atualizar a sua aplicação personalizada {:s}",
|
||||
"custom_appslist_name_required": "Deve fornecer um nome para a sua lista de aplicações personalizada",
|
||||
"domain_cert_gen_failed": "Não foi possível gerar o certificado",
|
||||
"domain_created": "Domínio criado com êxito",
|
||||
"domain_creation_failed": "Não foi possível criar o domínio",
|
||||
"domain_deleted": "Domínio removido com êxito",
|
||||
"domain_deletion_failed": "Não foi possível eliminar o domínio",
|
||||
"domain_dyndns_already_subscribed": "Já subscreveu um domínio DynDNS",
|
||||
"domain_dyndns_invalid": "Domínio inválido para ser utilizado com DynDNS",
|
||||
"domain_dyndns_root_unknown": "Domínio root (administrador) DynDNS desconhecido",
|
||||
"domain_exists": "O domínio já existe",
|
||||
"domain_uninstall_app_first": "Existem uma ou mais aplicações instaladas neste domínio. Por favor desinstale-as antes de proceder com a remoção do domínio.",
|
||||
"domain_unknown": "Domínio desconhecido",
|
||||
"domain_zone_exists": "Ficheiro para zona DMZ já existe",
|
||||
"domain_zone_not_found": "Ficheiro para zona DMZ não encontrado no domínio {:s}",
|
||||
"done": "Concluído.",
|
||||
"downloading": "Transferência em curso...",
|
||||
"dyndns_cron_installed": "Gestor de tarefas cron DynDNS instalado com êxito",
|
||||
"dyndns_cron_remove_failed": "Não foi possível remover o gestor de tarefas cron DynDNS",
|
||||
"dyndns_cron_removed": "Gestor de tarefas cron DynDNS removido com êxito",
|
||||
"dyndns_ip_update_failed": "Não foi possível atualizar o endereço IP a partir de DynDNS",
|
||||
"dyndns_ip_updated": "Endereço IP atualizado com êxito a partir de DynDNS",
|
||||
"dyndns_key_generating": "A chave DNS está a ser gerada, isto pode demorar um pouco...",
|
||||
"dyndns_registered": "Dom+inio DynDNS registado com êxito",
|
||||
"dyndns_registration_failed": "Não foi possível registar o domínio DynDNS: {:s}",
|
||||
"dyndns_unavailable": "Subdomínio DynDNS indisponível",
|
||||
"executing_script": "A executar o script...",
|
||||
"extracting": "Extração em curso...",
|
||||
"field_invalid": "Campo inválido '{:s}'",
|
||||
"firewall_reloaded": "Firewall recarregada com êxito",
|
||||
"hook_argument_missing": "Argumento em falta '{:s}'",
|
||||
"hook_choice_invalid": "Escolha inválida '{:s}'",
|
||||
"installation_complete": "Instalação concluída",
|
||||
"installation_failed": "A instalação falhou",
|
||||
"iptables_unavailable": "Não pode alterar aqui a iptables. Ou o seu kernel não o suporta ou está num espaço reservado.",
|
||||
"ldap_initialized": "LDAP inicializada com êxito",
|
||||
"license_undefined": "indefinido",
|
||||
"mail_alias_remove_failed": "Não foi possível remover a etiqueta de correio '{:s}'",
|
||||
"mail_domain_unknown": "Domínio de endereço de correio desconhecido '{:s}'",
|
||||
"mail_forward_remove_failed": "Não foi possível remover o reencaminhamento de correio '{:s}'",
|
||||
"maindomain_change_failed": "Incapaz alterar o domínio raiz",
|
||||
"maindomain_changed": "Domínio raiz alterado com êxito",
|
||||
"monitor_disabled": "Monitorização do servidor parada com êxito",
|
||||
"monitor_enabled": "Monitorização do servidor ativada com êxito",
|
||||
"monitor_glances_con_failed": "Não foi possível ligar ao servidor Glances",
|
||||
"monitor_not_enabled": "A monitorização do servidor não está ativa",
|
||||
"monitor_period_invalid": "Período de tempo inválido",
|
||||
"monitor_stats_file_not_found": "Ficheiro de estatísticas não encontrado",
|
||||
"monitor_stats_no_update": "Não existem estatísticas de monitorização para atualizar",
|
||||
"monitor_stats_period_unavailable": "Não existem estatísticas disponíveis para este período",
|
||||
"mountpoint_unknown": "Ponto de montagem desconhecido",
|
||||
"mysql_db_creation_failed": "Criação da base de dados MySQL falhou",
|
||||
"mysql_db_init_failed": "Inicialização da base de dados MySQL falhou",
|
||||
"mysql_db_initialized": "Base de dados MySQL iniciada com êxito",
|
||||
"new_domain_required": "Deve escrever um novo domínio principal",
|
||||
"no_appslist_found": "Não foi encontrada a lista de aplicações",
|
||||
"no_internet_connection": "O servidor não está ligado à Internet",
|
||||
"packages_no_upgrade": "Não existem pacotes para atualizar",
|
||||
"packages_upgrade_critical_later": "Os pacotes críticos ({:s}) serão atualizados depois",
|
||||
"packages_upgrade_failed": "Não foi possível atualizar todos os pacotes",
|
||||
"path_removal_failed": "Incapaz remover o caminho {:s}",
|
||||
"pattern_domain": "Deve ser um nome de domínio válido (p.e. meu-dominio.org)",
|
||||
"pattern_email": "Deve ser um endereço de correio válido (p.e. alguem@dominio.org)",
|
||||
"pattern_firstname": "Deve ser um primeiro nome válido",
|
||||
"pattern_lastname": "Deve ser um último nome válido",
|
||||
"pattern_listname": "Apenas são permitidos caracteres alfanuméricos e travessões",
|
||||
"pattern_password": "Deve ter no mínimo 3 caracteres",
|
||||
"pattern_port": "Deve ser um número de porta válido (entre 0-65535)",
|
||||
"pattern_username": "Must be lower-case alphanumeric and underscore characters only",
|
||||
"restore_confirm_yunohost_installed": "Quer mesmo restaurar um sistema já instalado? [{answers:s}]",
|
||||
"service_add_failed": "Incapaz adicionar serviço '{:s}'",
|
||||
"service_added": "Serviço adicionado com êxito",
|
||||
"service_already_started": "O serviço '{:s}' já está em execussão",
|
||||
"service_already_stopped": "O serviço '{:s}' já está parado",
|
||||
"service_cmd_exec_failed": "Incapaz executar o comando '{:s}'",
|
||||
"service_disable_failed": "Incapaz desativar o serviço '{:s}'",
|
||||
"service_disabled": "O serviço '{:s}' foi desativado com êxito",
|
||||
"service_enable_failed": "Incapaz de ativar o serviço '{:s}'",
|
||||
"service_enabled": "Serviço '{:s}' ativado com êxito",
|
||||
"service_no_log": "Não existem registos para mostrar do serviço '{:s}'",
|
||||
"service_remove_failed": "Incapaz de remover o serviço '{:s}'",
|
||||
"service_removed": "Serviço eliminado com êxito",
|
||||
"service_start_failed": "Não foi possível iniciar o serviço '{:s}'",
|
||||
"service_started": "O serviço '{:s} foi iniciado com êxito",
|
||||
"service_status_failed": "Incapaz determinar o estado do serviço '{:s}'",
|
||||
"service_stop_failed": "Incapaz parar o serviço '{:s}",
|
||||
"service_stopped": "O serviço '{:s}' foi parado com êxito",
|
||||
"service_unknown": "Serviço desconhecido '{:s}'",
|
||||
"ssowat_conf_generated": "Configuração SSOwat gerada com êxito",
|
||||
"ssowat_conf_updated": "Configuração persistente SSOwat atualizada com êxito",
|
||||
"system_upgraded": "Sistema atualizado com êxito",
|
||||
"system_username_exists": "O utilizador já existe no registo do sistema",
|
||||
"unexpected_error": "Ocorreu um erro inesperado",
|
||||
"unit_unknown": "Unidade desconhecida '{:s}'",
|
||||
"update_cache_failed": "Não foi possível atualizar os cabeçalhos APT",
|
||||
"updating_apt_cache": "A atualizar a lista de pacotes disponíveis...",
|
||||
"upgrade_complete": "Atualização completa",
|
||||
"upgrading_packages": "Atualização de pacotes em curso...",
|
||||
"user_created": "Utilizador criado com êxito",
|
||||
"user_creation_failed": "Não foi possível criar o utilizador",
|
||||
"user_deleted": "Utilizador eliminado com êxito",
|
||||
"user_deletion_failed": "Incapaz eliminar o utilizador",
|
||||
"user_info_failed": "Incapaz obter informações sobre o utilizador",
|
||||
"user_unknown": "Utilizador desconhecido",
|
||||
"user_update_failed": "Não foi possível atualizar o utilizador",
|
||||
"user_updated": "Utilizador atualizado com êxito",
|
||||
"yunohost_already_installed": "AYunoHost já está instalado",
|
||||
"yunohost_ca_creation_failed": "Incapaz criar o certificado de autoridade",
|
||||
"yunohost_configured": "YunoHost configurada com êxito",
|
||||
"yunohost_installing": "A instalar a YunoHost...",
|
||||
"action_invalid": "Acção Inválida '{action:s}'",
|
||||
"admin_password": "Senha de administração",
|
||||
"admin_password_change_failed": "Não foi possível alterar a senha",
|
||||
"admin_password_changed": "Senha de administração alterada com êxito",
|
||||
"app_already_installed": "{app:s} já está instalada",
|
||||
"app_extraction_failed": "Não foi possível extrair os ficheiros para instalação",
|
||||
"app_id_invalid": "ID da aplicação invélida",
|
||||
"app_install_files_invalid": "Ficheiros para instalação corrompidos",
|
||||
"app_location_already_used": "Já existe uma aplicação instalada neste diretório",
|
||||
"app_location_install_failed": "Não foi possível instalar a aplicação neste diretório",
|
||||
"app_manifest_invalid": "Manifesto da aplicação inválido",
|
||||
"app_no_upgrade": "Não existem aplicações para atualizar",
|
||||
"app_not_installed": "{app:s} não está instalada",
|
||||
"app_recent_version_required": "{:s} requer uma versão mais recente da moulinette",
|
||||
"app_removed": "{app:s} removida com êxito",
|
||||
"app_sources_fetch_failed": "Impossível obter os códigos fontes",
|
||||
"app_unknown": "Aplicação desconhecida",
|
||||
"app_upgrade_failed": "Unable to upgrade all apps",
|
||||
"app_upgraded": "{app:s} atualizada com êxito",
|
||||
"appslist_fetched": "Lista de aplicações processada com êxito",
|
||||
"appslist_removed": "Lista de aplicações removida com êxito",
|
||||
"appslist_retrieve_error": "Não foi possível obter a lista de aplicações remotas",
|
||||
"appslist_unknown": "Lista de aplicaçoes desconhecida",
|
||||
"ask_current_admin_password": "Senha de administração atual",
|
||||
"ask_email": "Correio eletrónico",
|
||||
"ask_firstname": "Primeiro nome",
|
||||
"ask_lastname": "Último nome",
|
||||
"ask_list_to_remove": "Lista para remover",
|
||||
"ask_main_domain": "Domínio principal",
|
||||
"ask_new_admin_password": "Senha de administração nova",
|
||||
"ask_password": "Senha",
|
||||
"backup_complete": "Backup completo",
|
||||
"backup_creating_archive": "A criar ficheiro de backup...",
|
||||
"backup_invalid_archive": "Arquivo de backup inválido",
|
||||
"backup_output_directory_not_empty": "A pasta de destino não se encontra vazia",
|
||||
"custom_app_url_required": "Deve proporcionar uma URL para atualizar a sua aplicação personalizada {app:s}",
|
||||
"custom_appslist_name_required": "Deve fornecer um nome para a sua lista de aplicações personalizada",
|
||||
"domain_cert_gen_failed": "Não foi possível gerar o certificado",
|
||||
"domain_created": "Domínio criado com êxito",
|
||||
"domain_creation_failed": "Não foi possível criar o domínio",
|
||||
"domain_deleted": "Domínio removido com êxito",
|
||||
"domain_deletion_failed": "Não foi possível eliminar o domínio",
|
||||
"domain_dyndns_already_subscribed": "Já subscreveu um domínio DynDNS",
|
||||
"domain_dyndns_invalid": "Domínio inválido para ser utilizado com DynDNS",
|
||||
"domain_dyndns_root_unknown": "Domínio root (administrador) DynDNS desconhecido",
|
||||
"domain_exists": "O domínio já existe",
|
||||
"domain_uninstall_app_first": "Existem uma ou mais aplicações instaladas neste domínio. Por favor desinstale-as antes de proceder com a remoção do domínio.",
|
||||
"domain_unknown": "Domínio desconhecido",
|
||||
"domain_zone_exists": "Ficheiro para zona DMZ já existe",
|
||||
"domain_zone_not_found": "Ficheiro para zona DMZ não encontrado no domínio {:s}",
|
||||
"done": "Concluído.",
|
||||
"downloading": "Transferência em curso...",
|
||||
"dyndns_cron_installed": "Gestor de tarefas cron DynDNS instalado com êxito",
|
||||
"dyndns_cron_remove_failed": "Não foi possível remover o gestor de tarefas cron DynDNS",
|
||||
"dyndns_cron_removed": "Gestor de tarefas cron DynDNS removido com êxito",
|
||||
"dyndns_ip_update_failed": "Não foi possível atualizar o endereço IP a partir de DynDNS",
|
||||
"dyndns_ip_updated": "Endereço IP atualizado com êxito a partir de DynDNS",
|
||||
"dyndns_key_generating": "A chave DNS está a ser gerada, isto pode demorar um pouco...",
|
||||
"dyndns_registered": "Dom+inio DynDNS registado com êxito",
|
||||
"dyndns_registration_failed": "Não foi possível registar o domínio DynDNS: {error:s}",
|
||||
"dyndns_unavailable": "Subdomínio DynDNS indisponível",
|
||||
"executing_script": "A executar o script...",
|
||||
"extracting": "Extração em curso...",
|
||||
"field_invalid": "Campo inválido '{:s}'",
|
||||
"firewall_reloaded": "Firewall recarregada com êxito",
|
||||
"hook_argument_missing": "Argumento em falta '{:s}'",
|
||||
"hook_choice_invalid": "Escolha inválida '{:s}'",
|
||||
"installation_complete": "Instalação concluída",
|
||||
"installation_failed": "A instalação falhou",
|
||||
"iptables_unavailable": "Não pode alterar aqui a iptables. Ou o seu kernel não o suporta ou está num espaço reservado.",
|
||||
"ldap_initialized": "LDAP inicializada com êxito",
|
||||
"license_undefined": "indefinido",
|
||||
"mail_alias_remove_failed": "Não foi possível remover a etiqueta de correio '{mail:s}'",
|
||||
"mail_domain_unknown": "Domínio de endereço de correio desconhecido '{domain:s}'",
|
||||
"mail_forward_remove_failed": "Não foi possível remover o reencaminhamento de correio '{mail:s}'",
|
||||
"maindomain_change_failed": "Incapaz alterar o domínio raiz",
|
||||
"maindomain_changed": "Domínio raiz alterado com êxito",
|
||||
"monitor_disabled": "Monitorização do servidor parada com êxito",
|
||||
"monitor_enabled": "Monitorização do servidor ativada com êxito",
|
||||
"monitor_glances_con_failed": "Não foi possível ligar ao servidor Glances",
|
||||
"monitor_not_enabled": "A monitorização do servidor não está ativa",
|
||||
"monitor_period_invalid": "Período de tempo inválido",
|
||||
"monitor_stats_file_not_found": "Ficheiro de estatísticas não encontrado",
|
||||
"monitor_stats_no_update": "Não existem estatísticas de monitorização para atualizar",
|
||||
"monitor_stats_period_unavailable": "Não existem estatísticas disponíveis para este período",
|
||||
"mountpoint_unknown": "Ponto de montagem desconhecido",
|
||||
"mysql_db_creation_failed": "Criação da base de dados MySQL falhou",
|
||||
"mysql_db_init_failed": "Inicialização da base de dados MySQL falhou",
|
||||
"mysql_db_initialized": "Base de dados MySQL iniciada com êxito",
|
||||
"new_domain_required": "Deve escrever um novo domínio principal",
|
||||
"no_appslist_found": "Não foi encontrada a lista de aplicações",
|
||||
"no_internet_connection": "O servidor não está ligado à Internet",
|
||||
"packages_no_upgrade": "Não existem pacotes para atualizar",
|
||||
"packages_upgrade_critical_later": "Os pacotes críticos ({packages:s}) serão atualizados depois",
|
||||
"packages_upgrade_failed": "Não foi possível atualizar todos os pacotes",
|
||||
"path_removal_failed": "Incapaz remover o caminho {:s}",
|
||||
"pattern_domain": "Deve ser um nome de domínio válido (p.e. meu-dominio.org)",
|
||||
"pattern_email": "Deve ser um endereço de correio válido (p.e. alguem@dominio.org)",
|
||||
"pattern_firstname": "Deve ser um primeiro nome válido",
|
||||
"pattern_lastname": "Deve ser um último nome válido",
|
||||
"pattern_listname": "Apenas são permitidos caracteres alfanuméricos e travessões",
|
||||
"pattern_password": "Deve ter no mínimo 3 caracteres",
|
||||
"pattern_port": "Deve ser um número de porta válido (entre 0-65535)",
|
||||
"pattern_username": "Must be lower-case alphanumeric and underscore characters only",
|
||||
"restore_confirm_yunohost_installed": "Quer mesmo restaurar um sistema já instalado? [{answers:s}]",
|
||||
"service_add_failed": "Incapaz adicionar serviço '{service:s}'",
|
||||
"service_added": "Serviço adicionado com êxito",
|
||||
"service_already_started": "O serviço '{service:s}' já está em execussão",
|
||||
"service_already_stopped": "O serviço '{service:s}' já está parado",
|
||||
"service_cmd_exec_failed": "Incapaz executar o comando '{command:s}'",
|
||||
"service_disable_failed": "Incapaz desativar o serviço '{service:s}'",
|
||||
"service_disabled": "O serviço '{service:s}' foi desativado com êxito",
|
||||
"service_enable_failed": "Incapaz de ativar o serviço '{service:s}'",
|
||||
"service_enabled": "Serviço '{service:s}' ativado com êxito",
|
||||
"service_no_log": "Não existem registos para mostrar do serviço '{service:s}'",
|
||||
"service_remove_failed": "Incapaz de remover o serviço '{service:s}'",
|
||||
"service_removed": "Serviço eliminado com êxito",
|
||||
"service_start_failed": "Não foi possível iniciar o serviço '{service:s}'",
|
||||
"service_started": "O serviço '{service:s}' foi iniciado com êxito",
|
||||
"service_status_failed": "Incapaz determinar o estado do serviço '{service:s}'",
|
||||
"service_stop_failed": "Incapaz parar o serviço '{service:s}'",
|
||||
"service_stopped": "O serviço '{service:s}' foi parado com êxito",
|
||||
"service_unknown": "Serviço desconhecido '{service:s}'",
|
||||
"ssowat_conf_generated": "Configuração SSOwat gerada com êxito",
|
||||
"ssowat_conf_updated": "Configuração persistente SSOwat atualizada com êxito",
|
||||
"system_upgraded": "Sistema atualizado com êxito",
|
||||
"system_username_exists": "O utilizador já existe no registo do sistema",
|
||||
"unexpected_error": "Ocorreu um erro inesperado",
|
||||
"unit_unknown": "Unidade desconhecida '{unit:s}'",
|
||||
"update_cache_failed": "Não foi possível atualizar os cabeçalhos APT",
|
||||
"updating_apt_cache": "A atualizar a lista de pacotes disponíveis...",
|
||||
"upgrade_complete": "Atualização completa",
|
||||
"upgrading_packages": "Atualização de pacotes em curso...",
|
||||
"user_created": "Utilizador criado com êxito",
|
||||
"user_creation_failed": "Não foi possível criar o utilizador",
|
||||
"user_deleted": "Utilizador eliminado com êxito",
|
||||
"user_deletion_failed": "Incapaz eliminar o utilizador",
|
||||
"user_info_failed": "Incapaz obter informações sobre o utilizador",
|
||||
"user_unknown": "Utilizador desconhecido",
|
||||
"user_update_failed": "Não foi possível atualizar o utilizador",
|
||||
"user_updated": "Utilizador atualizado com êxito",
|
||||
"yunohost_already_installed": "AYunoHost já está instalado",
|
||||
"yunohost_ca_creation_failed": "Incapaz criar o certificado de autoridade",
|
||||
"yunohost_configured": "YunoHost configurada com êxito",
|
||||
"yunohost_installing": "A instalar a YunoHost...",
|
||||
"yunohost_not_installed": "YunoHost ainda não está corretamente configurado. Por favor execute as 'ferramentas pós-instalação yunohost'."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1413,12 +1413,24 @@ def _encode_string(value):
|
|||
def _check_manifest_requirements(manifest):
|
||||
"""Check if required packages are met from the manifest"""
|
||||
requirements = manifest.get('requirements', dict())
|
||||
|
||||
# FIXME: Deprecate min_version key
|
||||
if 'min_version' in manifest:
|
||||
requirements['yunohost'] = '>> {0}'.format(manifest['min_version'])
|
||||
logger.debug("the manifest key 'min_version' is deprecated, "
|
||||
"use 'requirements' instead.")
|
||||
if not requirements:
|
||||
|
||||
# Validate multi-instance app
|
||||
if manifest.get('multi_instance', False):
|
||||
# Handle backward-incompatible change introduced in yunohost >= 2.3.6
|
||||
# See https://dev.yunohost.org/issues/156
|
||||
yunohost_req = requirements.get('yunohost', None)
|
||||
if (not yunohost_req or
|
||||
not packages.SpecifierSet(yunohost_req) & '>= 2.3.6'):
|
||||
raise MoulinetteError(errno.EINVAL, '{0}{1}'.format(
|
||||
m18n.g('colon', m18n.n('app_incompatible')),
|
||||
m18n.n('app_package_need_update')))
|
||||
elif not requirements:
|
||||
return
|
||||
|
||||
logger.info(m18n.n('app_requirements_checking'))
|
||||
|
@ -1429,7 +1441,8 @@ def _check_manifest_requirements(manifest):
|
|||
*requirements.keys(), strict=True, as_dict=True)
|
||||
except packages.PackageException as e:
|
||||
raise MoulinetteError(errno.EINVAL,
|
||||
m18n.n('app_requirements_failed', err=str(e)))
|
||||
m18n.n('app_requirements_failed',
|
||||
error=str(e)))
|
||||
|
||||
# Iterate over requirements
|
||||
for pkgname, spec in requirements.items():
|
||||
|
|
|
@ -39,7 +39,9 @@ from moulinette.core import MoulinetteError
|
|||
from moulinette.utils import filesystem
|
||||
from moulinette.utils.log import getActionLogger
|
||||
|
||||
from yunohost.app import app_info, app_ssowatconf, _is_installed, _parse_app_instance_name
|
||||
from yunohost.app import (
|
||||
app_info, app_ssowatconf, _is_installed, _parse_app_instance_name
|
||||
)
|
||||
from yunohost.hook import (
|
||||
hook_info, hook_callback, hook_exec, custom_hook_folder
|
||||
)
|
||||
|
@ -384,11 +386,11 @@ def backup_restore(auth, name, hooks=[], ignore_hooks=False,
|
|||
else:
|
||||
# Retrieve the domain from the backup
|
||||
try:
|
||||
with open("%s/yunohost/current_host" % tmp_dir, 'r') as f:
|
||||
with open("%s/conf/ynh/current_host" % tmp_dir, 'r') as f:
|
||||
domain = f.readline().rstrip()
|
||||
except IOError:
|
||||
logger.debug("unable to retrieve domain from "
|
||||
"'%s/yunohost/current_host'", tmp_dir, exc_info=1)
|
||||
logger.debug("unable to retrieve current_host from the backup",
|
||||
exc_info=1)
|
||||
raise MoulinetteError(errno.EIO, m18n.n('backup_invalid_archive'))
|
||||
|
||||
logger.debug("executing the post-install...")
|
||||
|
|
|
@ -37,6 +37,8 @@ from urllib import urlopen
|
|||
from moulinette.core import MoulinetteError
|
||||
from moulinette.utils.log import getActionLogger
|
||||
|
||||
from yunohost.service import service_regen_conf
|
||||
|
||||
logger = getActionLogger('yunohost.domain')
|
||||
|
||||
|
||||
|
@ -78,7 +80,6 @@ def domain_add(auth, domain, dyndns=False):
|
|||
dyndns -- Subscribe to DynDNS
|
||||
|
||||
"""
|
||||
from yunohost.service import service_regenconf
|
||||
from yunohost.hook import hook_callback
|
||||
|
||||
attr_dict = { 'objectClass' : ['mailDomain', 'top'] }
|
||||
|
@ -157,10 +158,8 @@ def domain_add(auth, domain, dyndns=False):
|
|||
|
||||
try:
|
||||
with open('/etc/yunohost/installed', 'r') as f:
|
||||
service_regenconf(service='nginx')
|
||||
service_regenconf(service='metronome')
|
||||
service_regenconf(service='dnsmasq')
|
||||
service_regenconf(service='rmilter')
|
||||
service_regen_conf(names=[
|
||||
'nginx', 'metronome', 'dnsmasq', 'rmilter'])
|
||||
os.system('yunohost app ssowatconf > /dev/null 2>&1')
|
||||
except IOError: pass
|
||||
except:
|
||||
|
@ -183,7 +182,6 @@ def domain_remove(auth, domain, force=False):
|
|||
force -- Force the domain removal
|
||||
|
||||
"""
|
||||
from yunohost.service import service_regenconf
|
||||
from yunohost.hook import hook_callback
|
||||
|
||||
if not force and domain not in domain_list(auth)['domains']:
|
||||
|
@ -206,9 +204,7 @@ def domain_remove(auth, domain, force=False):
|
|||
else:
|
||||
raise MoulinetteError(errno.EIO, m18n.n('domain_deletion_failed'))
|
||||
|
||||
service_regenconf(service='nginx')
|
||||
service_regenconf(service='metronome')
|
||||
service_regenconf(service='dnsmasq')
|
||||
service_regen_conf(names=['nginx', 'metronome', 'dnsmasq'])
|
||||
os.system('yunohost app ssowatconf > /dev/null 2>&1')
|
||||
|
||||
hook_callback('post_domain_remove', args=[domain])
|
||||
|
|
|
@ -176,6 +176,8 @@ def hook_list(action, list_by='name', show_info=False):
|
|||
def _append_folder(d, folder):
|
||||
# Iterate over and add hook from a folder
|
||||
for f in os.listdir(folder + action):
|
||||
if f[0] == '.' or f[-1] == '~':
|
||||
continue
|
||||
path = '%s%s/%s' % (folder, action, f)
|
||||
priority, name = _extract_filename_parts(f)
|
||||
_append_hook(d, priority, name, path)
|
||||
|
@ -205,14 +207,22 @@ def hook_list(action, list_by='name', show_info=False):
|
|||
return { 'hooks': result }
|
||||
|
||||
|
||||
def hook_callback(action, hooks=[], args=None):
|
||||
def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
||||
pre_callback=None, post_callback=None):
|
||||
"""
|
||||
Execute all scripts binded to an action
|
||||
|
||||
Keyword argument:
|
||||
action -- Action name
|
||||
hooks -- List of hooks names to execute
|
||||
args -- Ordered list of arguments to pass to the script
|
||||
args -- Ordered list of arguments to pass to the scripts
|
||||
no_trace -- Do not print each command that will be executed
|
||||
chdir -- The directory from where the scripts will be executed
|
||||
pre_callback -- An object to call before each script execution with
|
||||
(name, priority, path, args) as arguments and which must return
|
||||
the arguments to pass to the script
|
||||
post_callback -- An object to call after each script execution with
|
||||
(name, priority, path, succeed) as arguments
|
||||
|
||||
"""
|
||||
result = { 'succeed': {}, 'failed': {} }
|
||||
|
@ -252,26 +262,34 @@ def hook_callback(action, hooks=[], args=None):
|
|||
if not hooks_dict:
|
||||
return result
|
||||
|
||||
# Format arguments
|
||||
if args is None:
|
||||
args = []
|
||||
elif not isinstance(args, list):
|
||||
args = [args]
|
||||
# Validate callbacks
|
||||
if not callable(pre_callback):
|
||||
pre_callback = lambda name, priority, path, args: args
|
||||
if not callable(post_callback):
|
||||
post_callback = lambda name, priority, path, succeed: None
|
||||
|
||||
# Iterate over hooks and execute them
|
||||
for priority in sorted(hooks_dict):
|
||||
for name, info in iter(hooks_dict[priority].items()):
|
||||
state = 'succeed'
|
||||
filename = '%s-%s' % (priority, name)
|
||||
path = info['path']
|
||||
try:
|
||||
hook_exec(info['path'], args=args, raise_on_error=True)
|
||||
hook_args = pre_callback(name=name, priority=priority,
|
||||
path=path, args=args)
|
||||
hook_exec(path, args=hook_args, chdir=chdir,
|
||||
no_trace=no_trace, raise_on_error=True)
|
||||
except MoulinetteError as e:
|
||||
logger.error(str(e))
|
||||
state = 'failed'
|
||||
logger.error(str(e))
|
||||
post_callback(name=name, priority=priority, path=path,
|
||||
succeed=False)
|
||||
else:
|
||||
post_callback(name=name, priority=priority, path=path,
|
||||
succeed=True)
|
||||
try:
|
||||
result[state][name].append(info['path'])
|
||||
result[state][name].append(path)
|
||||
except KeyError:
|
||||
result[state][name] = [info['path']]
|
||||
result[state][name] = [path]
|
||||
return result
|
||||
|
||||
|
||||
|
@ -282,7 +300,7 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
|||
|
||||
Keyword argument:
|
||||
path -- Path of the script to execute
|
||||
args -- A list of arguments to pass to the script
|
||||
args -- Ordered list of arguments to pass to the script
|
||||
raise_on_error -- Raise if the script returns a non-zero exit code
|
||||
no_trace -- Do not print each command that will be executed
|
||||
chdir -- The directory from where the script will be executed
|
||||
|
|
|
@ -30,20 +30,18 @@ import glob
|
|||
import subprocess
|
||||
import errno
|
||||
import shutil
|
||||
import difflib
|
||||
import hashlib
|
||||
from difflib import unified_diff
|
||||
|
||||
from moulinette.core import MoulinetteError
|
||||
from moulinette.utils import log
|
||||
from moulinette.utils import log, filesystem
|
||||
|
||||
template_dir = os.getenv(
|
||||
'YUNOHOST_TEMPLATE_DIR',
|
||||
'/usr/share/yunohost/templates'
|
||||
)
|
||||
conf_backup_dir = os.getenv(
|
||||
'YUNOHOST_CONF_BACKUP_DIR',
|
||||
'/home/yunohost.backup/conffiles'
|
||||
)
|
||||
from yunohost.hook import hook_list, hook_callback
|
||||
|
||||
|
||||
base_conf_path = '/home/yunohost.conf'
|
||||
backup_conf_dir = os.path.join(base_conf_path, 'backup')
|
||||
pending_conf_dir = os.path.join(base_conf_path, 'pending')
|
||||
|
||||
logger = log.getActionLogger('yunohost.service')
|
||||
|
||||
|
@ -273,26 +271,196 @@ def service_log(name, number=50):
|
|||
return result
|
||||
|
||||
|
||||
def service_regenconf(service=None, force=False):
|
||||
def service_regen_conf(names=[], with_diff=False, force=False, dry_run=False,
|
||||
list_pending=False):
|
||||
"""
|
||||
Regenerate the configuration file(s) for a service and compare the result
|
||||
with the existing configuration file.
|
||||
Prints the differences between files if any.
|
||||
Regenerate the configuration file(s) for a service
|
||||
|
||||
Keyword argument:
|
||||
service -- Regenerate configuration for a specfic service
|
||||
force -- Override the current configuration with the newly generated
|
||||
one, even if it has been modified
|
||||
names -- Services name to regenerate configuration of
|
||||
with_diff -- Show differences in case of configuration changes
|
||||
force -- Override all manual modifications in configuration files
|
||||
dry_run -- Show what would have been regenerated
|
||||
list_pending -- List pending configuration files and exit
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
result = {}
|
||||
|
||||
if service is not None:
|
||||
hook_callback('conf_regen', [service], args=[force])
|
||||
logger.success(m18n.n('service_configured', service=service))
|
||||
else:
|
||||
hook_callback('conf_regen', args=[force])
|
||||
logger.success(m18n.n('service_configured_all'))
|
||||
# Return the list of pending conf
|
||||
if list_pending:
|
||||
pending_conf = _get_pending_conf(names)
|
||||
if with_diff:
|
||||
for service, conf_files in pending_conf.items():
|
||||
for system_path, pending_path in conf_files.items():
|
||||
pending_conf[service][system_path] = {
|
||||
'pending_conf': pending_path,
|
||||
'diff': _get_files_diff(
|
||||
system_path, pending_path, True),
|
||||
}
|
||||
return pending_conf
|
||||
|
||||
# Clean pending conf directory
|
||||
shutil.rmtree(pending_conf_dir, ignore_errors=True)
|
||||
filesystem.mkdir(pending_conf_dir, 0755, True)
|
||||
|
||||
# Format common hooks arguments
|
||||
common_args = [1 if force else 0, 1 if dry_run else 0]
|
||||
|
||||
# Execute hooks for pre-regen
|
||||
pre_args = ['pre',] + common_args
|
||||
def _pre_call(name, priority, path, args):
|
||||
# create the pending conf directory for the service
|
||||
service_pending_path = os.path.join(pending_conf_dir, name)
|
||||
filesystem.mkdir(service_pending_path, 0755, True, uid='admin')
|
||||
# return the arguments to pass to the script
|
||||
return pre_args + [service_pending_path,]
|
||||
pre_result = hook_callback('conf_regen', names, pre_callback=_pre_call)
|
||||
|
||||
# Update the services name
|
||||
names = pre_result['succeed'].keys()
|
||||
if not names:
|
||||
raise MoulinetteError(errno.EIO,
|
||||
m18n.n('service_regenconf_failed',
|
||||
services=', '.join(pre_result['failed'])))
|
||||
|
||||
# Set the processing method
|
||||
_regen = _process_regen_conf if not dry_run else lambda *a, **k: True
|
||||
|
||||
# Iterate over services and process pending conf
|
||||
for service, conf_files in _get_pending_conf(names).items():
|
||||
logger.info(m18n.n(
|
||||
'service_regenconf_pending_applying' if not dry_run else \
|
||||
'service_regenconf_dry_pending_applying',
|
||||
service=service))
|
||||
|
||||
conf_hashes = _get_conf_hashes(service)
|
||||
succeed_regen = {}
|
||||
failed_regen = {}
|
||||
|
||||
for system_path, pending_path in conf_files.items():
|
||||
logger.debug("processing pending conf '%s' to system conf '%s'",
|
||||
pending_path, system_path)
|
||||
conf_status = None
|
||||
regenerated = False
|
||||
|
||||
# Get the diff between files
|
||||
conf_diff = _get_files_diff(
|
||||
system_path, pending_path, True) if with_diff else None
|
||||
|
||||
# Check if the conf must be removed
|
||||
to_remove = True if os.path.getsize(pending_path) == 0 else False
|
||||
|
||||
# Retrieve and calculate hashes
|
||||
current_hash = conf_hashes.get(system_path, None)
|
||||
system_hash = _calculate_hash(system_path)
|
||||
new_hash = None if to_remove else _calculate_hash(pending_path)
|
||||
|
||||
# -> system conf does not exists
|
||||
if not system_hash:
|
||||
if to_remove:
|
||||
logger.debug("> system conf is already removed")
|
||||
os.remove(pending_path)
|
||||
continue
|
||||
if not current_hash or force:
|
||||
if force:
|
||||
logger.debug("> system conf has been manually removed")
|
||||
conf_status = 'force-created'
|
||||
else:
|
||||
logger.debug("> system conf does not exist yet")
|
||||
conf_status = 'created'
|
||||
regenerated = _regen(
|
||||
system_path, pending_path, save=False)
|
||||
else:
|
||||
logger.warning(m18n.n(
|
||||
'service_conf_file_manually_removed',
|
||||
conf=system_path))
|
||||
conf_status = 'removed'
|
||||
# -> system conf is not managed yet
|
||||
elif not current_hash:
|
||||
logger.debug("> system conf is not managed yet")
|
||||
if system_hash == new_hash:
|
||||
logger.debug("> no changes to system conf has been made")
|
||||
conf_status = 'managed'
|
||||
regenerated = True
|
||||
elif force and to_remove:
|
||||
regenerated = _regen(system_path)
|
||||
conf_status = 'force-removed'
|
||||
elif force:
|
||||
regenerated = _regen(system_path, pending_path)
|
||||
conf_status = 'force-updated'
|
||||
else:
|
||||
logger.warning(m18n.n('service_conf_file_not_managed',
|
||||
conf=system_path))
|
||||
conf_status = 'unmanaged'
|
||||
# -> system conf has not been manually modified
|
||||
elif system_hash == current_hash:
|
||||
if to_remove:
|
||||
regenerated = _regen(system_path)
|
||||
conf_status = 'removed'
|
||||
elif system_hash != new_hash:
|
||||
regenerated = _regen(system_path, pending_path)
|
||||
conf_status = 'updated'
|
||||
else:
|
||||
logger.debug("> system conf is already up-to-date")
|
||||
os.remove(pending_path)
|
||||
continue
|
||||
else:
|
||||
logger.debug("> system conf has been manually modified")
|
||||
if force:
|
||||
regenerated = _regen(system_path, pending_path)
|
||||
conf_status = 'force-updated'
|
||||
else:
|
||||
logger.warning(m18n.n(
|
||||
'service_conf_file_manually_modified',
|
||||
conf=system_path))
|
||||
conf_status = 'modified'
|
||||
|
||||
# Store the result
|
||||
conf_result = {'status': conf_status}
|
||||
if conf_diff is not None:
|
||||
conf_result['diff'] = conf_diff
|
||||
if regenerated:
|
||||
succeed_regen[system_path] = conf_result
|
||||
conf_hashes[system_path] = new_hash
|
||||
if os.path.isfile(pending_path):
|
||||
os.remove(pending_path)
|
||||
else:
|
||||
failed_regen[system_path] = conf_result
|
||||
|
||||
# Check for service conf changes
|
||||
if not succeed_regen and not failed_regen:
|
||||
logger.info(m18n.n('service_conf_up_to_date', service=service))
|
||||
continue
|
||||
elif not failed_regen:
|
||||
logger.success(m18n.n(
|
||||
'service_conf_updated' if not dry_run else \
|
||||
'service_conf_would_be_updated',
|
||||
service=service))
|
||||
if succeed_regen and not dry_run:
|
||||
_update_conf_hashes(service, conf_hashes)
|
||||
|
||||
# Append the service results
|
||||
result[service] = {
|
||||
'applied': succeed_regen,
|
||||
'pending': failed_regen
|
||||
}
|
||||
|
||||
# Return in case of dry run
|
||||
if dry_run:
|
||||
return result
|
||||
|
||||
# Execute hooks for post-regen
|
||||
post_args = ['post',] + common_args
|
||||
def _pre_call(name, priority, path, args):
|
||||
# append coma-separated applied changes for the service
|
||||
if name in result and result[name]['applied']:
|
||||
regen_conf_files = ','.join(result[name]['applied'].keys())
|
||||
else:
|
||||
regen_conf_files = ''
|
||||
return post_args + [regen_conf_files,]
|
||||
hook_callback('conf_regen', names, pre_callback=_pre_call)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _run_service_command(action, service):
|
||||
|
@ -380,175 +548,141 @@ def _tail(file, n, offset=None):
|
|||
except IOError: return []
|
||||
|
||||
|
||||
def _get_diff(string, filename):
|
||||
"""
|
||||
Show differences between a string and a file's content
|
||||
def _get_files_diff(orig_file, new_file, as_string=False, skip_header=True):
|
||||
"""Compare two files and return the differences
|
||||
|
||||
Keyword argument:
|
||||
string -- The string
|
||||
filename -- The file to compare with
|
||||
Read and compare two files. The differences are returned either as a delta
|
||||
in unified diff format or a formatted string if as_string is True. The
|
||||
header can also be removed if skip_header is True.
|
||||
|
||||
"""
|
||||
try:
|
||||
with open(filename, 'r') as f:
|
||||
file_lines = f.readlines()
|
||||
contents = [[], []]
|
||||
for i, path in enumerate((orig_file, new_file)):
|
||||
try:
|
||||
with open(path, 'r') as f:
|
||||
contents[i] = f.readlines()
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
string = string + '\n'
|
||||
new_lines = string.splitlines(True)
|
||||
if file_lines:
|
||||
while '\n' == file_lines[-1]:
|
||||
del file_lines[-1]
|
||||
return difflib.unified_diff(file_lines, new_lines)
|
||||
except IOError: return []
|
||||
# Compare files and format output
|
||||
diff = unified_diff(contents[0], contents[1])
|
||||
if skip_header:
|
||||
for i in range(2):
|
||||
try:
|
||||
next(diff)
|
||||
except:
|
||||
break
|
||||
if as_string:
|
||||
result = ''.join(line for line in diff)
|
||||
return result.rstrip()
|
||||
return diff
|
||||
|
||||
|
||||
def _hash(filename):
|
||||
"""
|
||||
Calculate a MD5 hash of a file
|
||||
|
||||
Keyword argument:
|
||||
filename -- The file to hash
|
||||
|
||||
"""
|
||||
def _calculate_hash(path):
|
||||
"""Calculate the MD5 hash of a file"""
|
||||
hasher = hashlib.md5()
|
||||
try:
|
||||
with open(filename, 'rb') as f:
|
||||
buf = f.read()
|
||||
hasher.update(buf)
|
||||
|
||||
with open(path, 'rb') as f:
|
||||
hasher.update(f.read())
|
||||
return hasher.hexdigest()
|
||||
except IOError:
|
||||
return 'no hash yet'
|
||||
return None
|
||||
|
||||
|
||||
def service_saferemove(service, conf_file, force=False):
|
||||
"""
|
||||
Check if the specific file has been modified before removing it.
|
||||
Backup the file in /home/yunohost.backup
|
||||
def _get_pending_conf(services=[]):
|
||||
"""Get pending configuration for service(s)
|
||||
|
||||
Keyword argument:
|
||||
service -- Service name of the file to delete
|
||||
conf_file -- The file to write
|
||||
force -- Force file deletion
|
||||
Iterate over the pending configuration directory for given service(s) - or
|
||||
all if empty - and look for files inside. Each file is considered as a
|
||||
pending configuration file and therefore must be in the same directory
|
||||
tree than the system file that it replaces.
|
||||
The result is returned as a dict of services with pending configuration as
|
||||
key and a dict of `system_conf_path` => `pending_conf_path` as value.
|
||||
|
||||
"""
|
||||
deleted = False
|
||||
result = {}
|
||||
if not os.path.isdir(pending_conf_dir):
|
||||
return result
|
||||
if not services:
|
||||
services = os.listdir(pending_conf_dir)
|
||||
for name in services:
|
||||
service_conf = {}
|
||||
service_pending_path = os.path.join(pending_conf_dir, name)
|
||||
path_index = len(service_pending_path)
|
||||
for root, dirs, files in os.walk(service_pending_path):
|
||||
for filename in files:
|
||||
pending_path = os.path.join(root, filename)
|
||||
service_conf[pending_path[path_index:]] = pending_path
|
||||
if service_conf:
|
||||
result[name] = service_conf
|
||||
return result
|
||||
|
||||
|
||||
def _get_conf_hashes(service):
|
||||
"""Get the registered conf hashes for a service"""
|
||||
try:
|
||||
return _get_services()[service]['conffiles']
|
||||
except:
|
||||
logger.debug("unable to retrieve conf hashes for %s",
|
||||
service, exc_info=1)
|
||||
return {}
|
||||
|
||||
|
||||
def _update_conf_hashes(service, hashes):
|
||||
"""Update the registered conf hashes for a service"""
|
||||
logger.debug("updating conf hashes for '%s' with: %s",
|
||||
service, hashes)
|
||||
services = _get_services()
|
||||
|
||||
if not os.path.exists(conf_file):
|
||||
try:
|
||||
del services[service]['conffiles'][conf_file]
|
||||
except KeyError: pass
|
||||
return True
|
||||
|
||||
# Backup existing file
|
||||
date = time.strftime("%Y%m%d.%H%M%S")
|
||||
conf_backup_file = conf_backup_dir + conf_file +'-'+ date
|
||||
process = subprocess.Popen(
|
||||
['install', '-D', conf_file, conf_backup_file]
|
||||
)
|
||||
process.wait()
|
||||
|
||||
# Retrieve hashes
|
||||
if not 'conffiles' in services[service]:
|
||||
services[service]['conffiles'] = {}
|
||||
|
||||
if conf_file in services[service]['conffiles']:
|
||||
previous_hash = services[service]['conffiles'][conf_file]
|
||||
else:
|
||||
previous_hash = 'no hash yet'
|
||||
|
||||
current_hash = _hash(conf_file)
|
||||
|
||||
# Handle conflicts
|
||||
if force or previous_hash == current_hash:
|
||||
os.remove(conf_file)
|
||||
try:
|
||||
del services[service]['conffiles'][conf_file]
|
||||
except KeyError: pass
|
||||
deleted = True
|
||||
else:
|
||||
services[service]['conffiles'][conf_file] = previous_hash
|
||||
os.remove(conf_backup_file)
|
||||
if len(previous_hash) == 32 or previous_hash[-32:] != current_hash:
|
||||
logger.warning(m18n.n('service_configuration_conflict',
|
||||
file=conf_file))
|
||||
|
||||
service_conf = services.get(service, {})
|
||||
service_conf['conffiles'] = hashes
|
||||
services[service] = service_conf
|
||||
_save_services(services)
|
||||
|
||||
return deleted
|
||||
|
||||
def _process_regen_conf(system_conf, new_conf=None, save=True):
|
||||
"""Regenerate a given system configuration file
|
||||
|
||||
def service_safecopy(service, new_conf_file, conf_file, force=False):
|
||||
"""
|
||||
Check if the specific file has been modified and display differences.
|
||||
Stores the file hash in the services.yml file
|
||||
|
||||
Keyword argument:
|
||||
service -- Service name attached to the conf file
|
||||
new_conf_file -- Path to the desired conf file
|
||||
conf_file -- Path to the targeted conf file
|
||||
force -- Force file overriding
|
||||
Replace a given system configuration file by a new one or delete it if
|
||||
new_conf is None. A backup of the file - keeping its directory tree - will
|
||||
be done in the backup conf directory before any operation if save is True.
|
||||
|
||||
"""
|
||||
regenerated = False
|
||||
services = _get_services()
|
||||
|
||||
if not os.path.exists(new_conf_file):
|
||||
raise MoulinetteError(errno.EIO, m18n.n('no_such_conf_file', file=new_conf_file))
|
||||
|
||||
with open(new_conf_file, 'r') as f:
|
||||
new_conf = ''.join(f.readlines()).rstrip()
|
||||
|
||||
# Backup existing file
|
||||
date = time.strftime("%Y%m%d.%H%M%S")
|
||||
conf_backup_file = conf_backup_dir + conf_file +'-'+ date
|
||||
if os.path.exists(conf_file):
|
||||
process = subprocess.Popen(
|
||||
['install', '-D', conf_file, conf_backup_file]
|
||||
)
|
||||
process.wait()
|
||||
else:
|
||||
logger.info(m18n.n('service_add_configuration', file=conf_file))
|
||||
|
||||
# Add the service if it does not exist
|
||||
if service not in services.keys():
|
||||
services[service] = {}
|
||||
|
||||
# Retrieve hashes
|
||||
if not 'conffiles' in services[service]:
|
||||
services[service]['conffiles'] = {}
|
||||
|
||||
if conf_file in services[service]['conffiles']:
|
||||
previous_hash = services[service]['conffiles'][conf_file]
|
||||
else:
|
||||
previous_hash = 'no hash yet'
|
||||
|
||||
current_hash = _hash(conf_file)
|
||||
diff = list(_get_diff(new_conf, conf_file))
|
||||
|
||||
# Handle conflicts
|
||||
if force or previous_hash == current_hash:
|
||||
with open(conf_file, 'w') as f: f.write(new_conf)
|
||||
new_hash = _hash(conf_file)
|
||||
if previous_hash != new_hash:
|
||||
regenerated = True
|
||||
elif len(diff) == 0:
|
||||
new_hash = _hash(conf_file)
|
||||
else:
|
||||
new_hash = previous_hash
|
||||
if (len(previous_hash) == 32 or previous_hash[-32:] != current_hash):
|
||||
logger.warning('{0} {1}'.format(
|
||||
m18n.n('service_configuration_conflict', file=conf_file),
|
||||
m18n.n('show_diff', diff=''.join(diff))))
|
||||
|
||||
# Remove the backup file if the configuration has not changed
|
||||
if new_hash == previous_hash:
|
||||
try:
|
||||
os.remove(conf_backup_file)
|
||||
except OSError: pass
|
||||
|
||||
services[service]['conffiles'][conf_file] = new_hash
|
||||
_save_services(services)
|
||||
|
||||
return regenerated
|
||||
if save:
|
||||
backup_path = os.path.join(backup_conf_dir, '{0}-{1}'.format(
|
||||
system_conf.lstrip('/'), time.strftime("%Y%m%d.%H%M%S")))
|
||||
backup_dir = os.path.dirname(backup_path)
|
||||
if not os.path.isdir(backup_dir):
|
||||
filesystem.mkdir(backup_dir, 0755, True)
|
||||
shutil.copy2(system_conf, backup_path)
|
||||
logger.info(m18n.n('service_conf_file_backed_up',
|
||||
conf=system_conf, backup=backup_path))
|
||||
try:
|
||||
if not new_conf:
|
||||
os.remove(system_conf)
|
||||
logger.info(m18n.n('service_conf_file_removed',
|
||||
conf=system_conf))
|
||||
else:
|
||||
system_dir = os.path.dirname(system_conf)
|
||||
if not os.path.isdir(system_dir):
|
||||
filesystem.mkdir(system_dir, 0755, True)
|
||||
shutil.copyfile(new_conf, system_conf)
|
||||
logger.info(m18n.n('service_conf_file_updated',
|
||||
conf=system_conf))
|
||||
except:
|
||||
if not new_conf and os.path.exists(system_conf):
|
||||
logger.warning(m18n.n('service_conf_file_remove_failed',
|
||||
conf=system_conf),
|
||||
exc_info=1)
|
||||
return False
|
||||
elif new_conf:
|
||||
try:
|
||||
copy_succeed = os.path.samefile(system_conf, new_conf)
|
||||
except:
|
||||
copy_succeed = False
|
||||
finally:
|
||||
if not copy_succeed:
|
||||
logger.warning(m18n.n('service_conf_file_copy_failed',
|
||||
conf=system_conf, new=new_conf),
|
||||
exc_info=1)
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -43,7 +43,7 @@ from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, a
|
|||
from yunohost.domain import domain_add, domain_list, get_public_ip
|
||||
from yunohost.dyndns import dyndns_subscribe
|
||||
from yunohost.firewall import firewall_upnp, firewall_reload
|
||||
from yunohost.service import service_status, service_regenconf, service_log
|
||||
from yunohost.service import service_status, service_regen_conf, service_log
|
||||
from yunohost.monitor import monitor_disk, monitor_network, monitor_system
|
||||
from yunohost.utils.packages import ynh_packages_version
|
||||
|
||||
|
@ -152,7 +152,7 @@ def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
|
|||
|
||||
try:
|
||||
with open('/etc/yunohost/installed', 'r') as f:
|
||||
service_regenconf()
|
||||
service_regen_conf()
|
||||
except IOError: pass
|
||||
|
||||
logger.success(m18n.n('maindomain_changed'))
|
||||
|
@ -170,13 +170,10 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
|||
"""
|
||||
dyndns = not ignore_dyndns
|
||||
|
||||
try:
|
||||
with open('/etc/yunohost/installed') as f: pass
|
||||
except IOError:
|
||||
logger.info(m18n.n('yunohost_installing'))
|
||||
else:
|
||||
raise MoulinetteError(errno.EPERM, m18n.n('yunohost_already_installed'))
|
||||
|
||||
# Do some checks at first
|
||||
if os.path.isfile('/etc/yunohost/installed'):
|
||||
raise MoulinetteError(errno.EPERM,
|
||||
m18n.n('yunohost_already_installed'))
|
||||
if len(domain.split('.')) >= 3 and not ignore_dyndns:
|
||||
try:
|
||||
r = requests.get('https://dyndns.yunohost.org/domains')
|
||||
|
@ -187,10 +184,23 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
|||
dyndomain = '.'.join(domain.split('.')[1:])
|
||||
if dyndomain in dyndomains:
|
||||
if requests.get('https://dyndns.yunohost.org/test/%s' % domain).status_code == 200:
|
||||
dyndns=True
|
||||
dyndns = True
|
||||
else:
|
||||
raise MoulinetteError(errno.EEXIST,
|
||||
m18n.n('dyndns_unavailable'))
|
||||
m18n.n('dyndns_unavailable'))
|
||||
|
||||
logger.info(m18n.n('yunohost_installing'))
|
||||
|
||||
# Instantiate LDAP Authenticator
|
||||
auth = init_authenticator(('ldap', 'default'),
|
||||
{'uri': "ldap://localhost:389",
|
||||
'base_dn': "dc=yunohost,dc=org",
|
||||
'user_rdn': "cn=admin" })
|
||||
auth.authenticate('yunohost')
|
||||
|
||||
# Initialize LDAP for YunoHost
|
||||
# TODO: Improve this part by integrate ldapinit into conf_regen hook
|
||||
tools_ldapinit(auth)
|
||||
|
||||
# Create required folders
|
||||
folders_to_create = [
|
||||
|
@ -230,6 +240,7 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
|||
os.system('chmod 644 /etc/ssowat/conf.json.persistent')
|
||||
|
||||
# Create SSL CA
|
||||
service_regen_conf(['ssl'], force=True)
|
||||
ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
|
||||
command_list = [
|
||||
'echo "01" > %s/serial' % ssl_dir,
|
||||
|
@ -247,16 +258,6 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
|||
raise MoulinetteError(errno.EPERM,
|
||||
m18n.n('yunohost_ca_creation_failed'))
|
||||
|
||||
# Instantiate LDAP Authenticator
|
||||
auth = init_authenticator(('ldap', 'default'),
|
||||
{ 'uri': "ldap://localhost:389",
|
||||
'base_dn': "dc=yunohost,dc=org",
|
||||
'user_rdn': "cn=admin" })
|
||||
auth.authenticate('yunohost')
|
||||
|
||||
# Initialize YunoHost LDAP base
|
||||
tools_ldapinit(auth)
|
||||
|
||||
# New domain config
|
||||
tools_maindomain(auth, old_domain='yunohost.org', new_domain=domain, dyndns=dyndns)
|
||||
|
||||
|
@ -275,7 +276,7 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
|||
os.system('update-rc.d yunohost-firewall enable')
|
||||
os.system('service yunohost-firewall start')
|
||||
|
||||
service_regenconf(force=True)
|
||||
service_regen_conf(force=True)
|
||||
|
||||
logger.success(m18n.n('yunohost_configured'))
|
||||
|
||||
|
@ -503,4 +504,4 @@ def tools_diagnosis(auth, private=False):
|
|||
# Domains
|
||||
diagnosis['private']['domains'] = domain_list(auth)['domains']
|
||||
|
||||
return diagnosis
|
||||
return diagnosis
|
||||
|
|
|
@ -98,17 +98,22 @@ class Specifier(object):
|
|||
}
|
||||
|
||||
def __init__(self, spec):
|
||||
match = self._regex.search(spec)
|
||||
if not match:
|
||||
raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
|
||||
if isinstance(spec, basestring):
|
||||
match = self._regex.search(spec)
|
||||
if not match:
|
||||
raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
|
||||
|
||||
self._spec = (
|
||||
match.group("relation").strip(),
|
||||
match.group("version").strip(),
|
||||
)
|
||||
self._spec = (
|
||||
match.group("relation").strip(),
|
||||
match.group("version").strip(),
|
||||
)
|
||||
elif isinstance(spec, self.__class__):
|
||||
self._spec = spec._spec
|
||||
else:
|
||||
return NotImplemented
|
||||
|
||||
def __repr__(self):
|
||||
return "<Specifier({1!r})>".format(str(self))
|
||||
return "<Specifier({0!r})>".format(str(self))
|
||||
|
||||
def __str__(self):
|
||||
return "{0}{1}".format(*self._spec)
|
||||
|
@ -138,6 +143,12 @@ class Specifier(object):
|
|||
|
||||
return self._spec != other._spec
|
||||
|
||||
def __and__(self, other):
|
||||
return self.intersection(other)
|
||||
|
||||
def __or__(self, other):
|
||||
return self.union(other)
|
||||
|
||||
def _get_relation(self, op):
|
||||
return getattr(self, "_compare_{0}".format(self._relations[op]))
|
||||
|
||||
|
@ -167,7 +178,79 @@ class Specifier(object):
|
|||
def __contains__(self, item):
|
||||
return self.contains(item)
|
||||
|
||||
def intersection(self, other):
|
||||
"""Make the intersection of two specifiers
|
||||
|
||||
Return a new `SpecifierSet` with version specifier(s) common to the
|
||||
specifier and the other.
|
||||
|
||||
Example:
|
||||
>>> Specifier('>= 2.2') & '>> 2.2.1' == '>> 2.2.1'
|
||||
>>> Specifier('>= 2.2') & '<< 2.3' == '>= 2.2, << 2.3'
|
||||
|
||||
"""
|
||||
if isinstance(other, basestring):
|
||||
try:
|
||||
other = self.__class__(other)
|
||||
except InvalidSpecifier:
|
||||
return NotImplemented
|
||||
elif not isinstance(other, self.__class__):
|
||||
return NotImplemented
|
||||
|
||||
# store spec parts for easy access
|
||||
rel1, v1 = self.relation, self.version
|
||||
rel2, v2 = other.relation, other.version
|
||||
result = []
|
||||
|
||||
if other == self:
|
||||
result = [other]
|
||||
elif rel1 == '=':
|
||||
result = [self] if v1 in other else None
|
||||
elif rel2 == '=':
|
||||
result = [other] if v2 in self else None
|
||||
elif v1 == v2:
|
||||
result = [other if rel1[1] == '=' else self]
|
||||
elif v2 in self or v1 in other:
|
||||
is_self_greater = version_compare(v1, v2) > 0
|
||||
if rel1[0] == rel2[0]:
|
||||
if rel1[0] == '>':
|
||||
result = [self if is_self_greater else other]
|
||||
else:
|
||||
result = [other if is_self_greater else self]
|
||||
else:
|
||||
result = [self, other]
|
||||
return SpecifierSet(result if result is not None else '')
|
||||
|
||||
def union(self, other):
|
||||
"""Make the union of two version specifiers
|
||||
|
||||
Return a new `SpecifierSet` with version specifiers from the
|
||||
specifier and the other.
|
||||
|
||||
Example:
|
||||
>>> Specifier('>= 2.2') | '<< 2.3' == '>= 2.2, << 2.3'
|
||||
|
||||
"""
|
||||
if isinstance(other, basestring):
|
||||
try:
|
||||
other = self.__class__(other)
|
||||
except InvalidSpecifier:
|
||||
return NotImplemented
|
||||
elif not isinstance(other, self.__class__):
|
||||
return NotImplemented
|
||||
|
||||
return SpecifierSet([self, other])
|
||||
|
||||
def contains(self, item):
|
||||
"""Check if the specifier contains an other
|
||||
|
||||
Return whether the item is contained in the version specifier.
|
||||
|
||||
Example:
|
||||
>>> '2.2.1' in Specifier('<< 2.3')
|
||||
>>> '2.4' not in Specifier('<< 2.3')
|
||||
|
||||
"""
|
||||
return self._get_relation(self.relation)(item, self.version)
|
||||
|
||||
|
||||
|
@ -181,7 +264,9 @@ class SpecifierSet(object):
|
|||
"""
|
||||
|
||||
def __init__(self, specifiers):
|
||||
specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
|
||||
if isinstance(specifiers, basestring):
|
||||
specifiers = [s.strip() for s in specifiers.split(",")
|
||||
if s.strip()]
|
||||
|
||||
parsed = set()
|
||||
for specifier in specifiers:
|
||||
|
@ -190,7 +275,7 @@ class SpecifierSet(object):
|
|||
self._specs = frozenset(parsed)
|
||||
|
||||
def __repr__(self):
|
||||
return "<SpecifierSet({1!r})>".format(str(self))
|
||||
return "<SpecifierSet({0!r})>".format(str(self))
|
||||
|
||||
def __str__(self):
|
||||
return ",".join(sorted(str(s) for s in self._specs))
|
||||
|
@ -199,14 +284,10 @@ class SpecifierSet(object):
|
|||
return hash(self._specs)
|
||||
|
||||
def __and__(self, other):
|
||||
if isinstance(other, basestring):
|
||||
other = SpecifierSet(other)
|
||||
elif not isinstance(other, SpecifierSet):
|
||||
return NotImplemented
|
||||
return self.intersection(other)
|
||||
|
||||
specifier = SpecifierSet()
|
||||
specifier._specs = frozenset(self._specs | other._specs)
|
||||
return specifiers
|
||||
def __or__(self, other):
|
||||
return self.union(other)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, basestring):
|
||||
|
@ -237,7 +318,69 @@ class SpecifierSet(object):
|
|||
def __contains__(self, item):
|
||||
return self.contains(item)
|
||||
|
||||
def intersection(self, other):
|
||||
"""Make the intersection of two specifiers sets
|
||||
|
||||
Return a new `SpecifierSet` with version specifier(s) common to the
|
||||
set and the other.
|
||||
|
||||
Example:
|
||||
>>> SpecifierSet('>= 2.2') & '>> 2.2.1' == '>> 2.2.1'
|
||||
>>> SpecifierSet('>= 2.2, << 2.4') & '<< 2.3' == '>= 2.2, << 2.3'
|
||||
>>> SpecifierSet('>= 2.2, << 2.3') & '>= 2.4' == ''
|
||||
|
||||
"""
|
||||
if isinstance(other, basestring):
|
||||
other = SpecifierSet(other)
|
||||
elif not isinstance(other, SpecifierSet):
|
||||
return NotImplemented
|
||||
|
||||
specifiers = set(self._specs | other._specs)
|
||||
intersection = [specifiers.pop()] if specifiers else []
|
||||
|
||||
for specifier in specifiers:
|
||||
parsed = set()
|
||||
for spec in intersection:
|
||||
inter = spec & specifier
|
||||
if not inter:
|
||||
parsed.clear()
|
||||
break
|
||||
# TODO: validate with other specs in parsed
|
||||
parsed.update(inter._specs)
|
||||
intersection = parsed
|
||||
if not intersection:
|
||||
break
|
||||
return SpecifierSet(intersection)
|
||||
|
||||
def union(self, other):
|
||||
"""Make the union of two specifiers sets
|
||||
|
||||
Return a new `SpecifierSet` with version specifiers from the set
|
||||
and the other.
|
||||
|
||||
Example:
|
||||
>>> SpecifierSet('>= 2.2') | '<< 2.3' == '>= 2.2, << 2.3'
|
||||
|
||||
"""
|
||||
if isinstance(other, basestring):
|
||||
other = SpecifierSet(other)
|
||||
elif not isinstance(other, SpecifierSet):
|
||||
return NotImplemented
|
||||
|
||||
specifiers = SpecifierSet([])
|
||||
specifiers._specs = frozenset(self._specs | other._specs)
|
||||
return specifiers
|
||||
|
||||
def contains(self, item):
|
||||
"""Check if the set contains a version specifier
|
||||
|
||||
Return whether the item is contained in all version specifiers.
|
||||
|
||||
Example:
|
||||
>>> '2.2.1' in SpecifierSet('>= 2.2, << 2.3')
|
||||
>>> '2.4' not in SpecifierSet('>= 2.2, << 2.3')
|
||||
|
||||
"""
|
||||
return all(
|
||||
s.contains(item)
|
||||
for s in self._specs
|
||||
|
|
Loading…
Add table
Reference in a new issue