mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge branch 'stretch-unstable' into enh-postgresql-locale-misconfigured
This commit is contained in:
commit
d6e7295dfa
153 changed files with 11697 additions and 8376 deletions
4
.github/FUNDING.yml
vendored
Normal file
4
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
custom: https://donate.yunohost.org
|
||||||
|
liberapay: YunoHost
|
101
.gitlab-ci.yml
Normal file
101
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
stages:
|
||||||
|
- postinstall
|
||||||
|
- tests
|
||||||
|
|
||||||
|
.tests:
|
||||||
|
image: after-postinstall
|
||||||
|
before_script:
|
||||||
|
- apt-get install python-pip -y
|
||||||
|
- mkdir -p .pip
|
||||||
|
- pip install -U pip
|
||||||
|
- hash -d pip
|
||||||
|
- pip --cache-dir=.pip install pytest pytest-sugar pytest-mock requests-mock mock
|
||||||
|
- pushd src/yunohost/tests
|
||||||
|
- >
|
||||||
|
if [ ! -d "./apps" ]; then
|
||||||
|
git clone https://github.com/YunoHost/test_apps ./apps
|
||||||
|
fi
|
||||||
|
- cd apps
|
||||||
|
- git pull > /dev/null 2>&1
|
||||||
|
- popd
|
||||||
|
- export PYTEST_ADDOPTS="--color=yes"
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- .pip
|
||||||
|
- src/yunohost/tests/apps
|
||||||
|
key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
|
||||||
|
|
||||||
|
postinstall:
|
||||||
|
image: before-postinstall
|
||||||
|
stage: postinstall
|
||||||
|
script:
|
||||||
|
- yunohost tools postinstall -d domain.tld -p the_password --ignore-dyndns
|
||||||
|
|
||||||
|
root-tests:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- py.test tests
|
||||||
|
|
||||||
|
test-apps:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- cd src/yunohost
|
||||||
|
- py.test tests/test_apps.py
|
||||||
|
|
||||||
|
test-appscatalog:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- cd src/yunohost
|
||||||
|
- py.test tests/test_appscatalog.py
|
||||||
|
|
||||||
|
test-appurl:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- cd src/yunohost
|
||||||
|
- py.test tests/test_appurl.py
|
||||||
|
|
||||||
|
test-backuprestore:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- cd src/yunohost
|
||||||
|
- py.test tests/test_backuprestore.py
|
||||||
|
|
||||||
|
test-changeurl:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- cd src/yunohost
|
||||||
|
- py.test tests/test_changeurl.py
|
||||||
|
|
||||||
|
test-permission:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- cd src/yunohost
|
||||||
|
- py.test tests/test_permission.py
|
||||||
|
|
||||||
|
test-settings:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- cd src/yunohost
|
||||||
|
- py.test tests/test_settings.py
|
||||||
|
|
||||||
|
test-user-group:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- cd src/yunohost
|
||||||
|
- py.test tests/test_user-group.py
|
||||||
|
|
||||||
|
test-regenconf:
|
||||||
|
extends: .tests
|
||||||
|
stage: tests
|
||||||
|
script:
|
||||||
|
- cd src/yunohost
|
||||||
|
- py.test tests/test_regenconf.py
|
61
README.md
61
README.md
|
@ -1,48 +1,43 @@
|
||||||
|
<p align="center">
|
||||||
|
<img alt="YunoHost" src="https://raw.githubusercontent.com/YunoHost/doc/master/images/logo_roundcorner.png" width="100px" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1 align="center">YunoHost</h1>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
[](https://travis-ci.org/YunoHost/yunohost)
|
[](https://travis-ci.org/YunoHost/yunohost)
|
||||||
[](https://github.com/YunoHost/yunohost/blob/stretch-unstable/LICENSE)
|
[](https://github.com/YunoHost/yunohost/blob/stretch-unstable/LICENSE)
|
||||||
|
[](https://mastodon.social/@yunohost)
|
||||||
|
|
||||||
# YunoHost core
|
</div>
|
||||||
|
|
||||||
This repository is the core of YunoHost code.
|
YunoHost is an operating system aiming to simplify as much as possible the administration of a server.
|
||||||
|
|
||||||
|
This repository corresponds to the core code of YunoHost, mainly written in Python and Bash.
|
||||||
|
|
||||||
|
- [Project features](https://yunohost.org/#/whatsyunohost)
|
||||||
- [Project website](https://yunohost.org)
|
- [Project website](https://yunohost.org)
|
||||||
- [Bugtracker](https://github.com/YunoHost/issues).
|
- [Install documentation](https://yunohost.org/install)
|
||||||
|
- [Issue tracker](https://github.com/YunoHost/issues)
|
||||||
|
|
||||||
|
# Screenshots
|
||||||
|
|
||||||
|
Webadmin ([Yunohost-Admin](https://github.com/YunoHost/yunohost-admin)) | Single sign-on user portal ([SSOwat](https://github.com/YunoHost/ssowat))
|
||||||
|
--- | ---
|
||||||
|
 | 
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
- You can develop on this repository using [ynh-dev](https://github.com/YunoHost/ynh-dev) with `use-git` sub-command.
|
- You can learn how to get started with developing on YunoHost by reading [this piece of documentation](https://yunohost.org/dev).
|
||||||
- On this repository we are [following this workflow](https://yunohost.org/#/build_system_en): `stable ← testing ← unstable ← your_branch`.
|
- Come chat with us on the [dev chatroom](https://yunohost.org/#/chat_rooms) !
|
||||||
- Note: If you modify Python scripts, you will have to modifiy the actions map.
|
|
||||||
- You can help translate YunoHost on our [translation platform](https://translate.yunohost.org/engage/yunohost/?utm_source=widget)
|
- You can help translate YunoHost on our [translation platform](https://translate.yunohost.org/engage/yunohost/?utm_source=widget)
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
<img src="https://translate.yunohost.org/widgets/yunohost/-/multi-auto.svg" alt="Translation status" />
|
<img src="https://translate.yunohost.org/widgets/yunohost/-/multi-auto.svg" alt="Translation status" />
|
||||||
|
</p>
|
||||||
|
|
||||||
## Repository content
|
|
||||||
|
|
||||||
- [YunoHost core Python 2.7 scripts](./src/yunohost).
|
|
||||||
- [An actionsmap](./data/actionsmap/yunohost.yml) used by moulinette.
|
|
||||||
- [Services configuration templates](./data/templates).
|
|
||||||
- [Hooks](./data/hooks).
|
|
||||||
- [Locales](./locales) for translations of `yunohost` command.
|
|
||||||
- [Shell helpers](./helpers.d) for [application packaging](https://yunohost.org/#/packaging_apps_helpers_en).
|
|
||||||
- [Modules for the XMPP server Metronome](./lib/metronome/modules).
|
|
||||||
- [Debian files](./debian) for package creation.
|
|
||||||
|
|
||||||
## How does it work?
|
|
||||||
|
|
||||||
- Python core scripts are accessible through two interfaces thanks to the [moulinette framework](https://github.com/YunoHost/moulinette):
|
|
||||||
- [CLI](https://en.wikipedia.org/wiki/Command-line_interface) for `yunohost` command.
|
|
||||||
- [API](https://en.wikipedia.org/wiki/Application_programming_interface) for [web administration module](https://github.com/YunoHost/yunohost-admin) (other modules could be implemented).
|
|
||||||
- You can find more details about how YunoHost works on this [documentation (in French)](https://yunohost.org/#/package_list_fr).
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- [Python 2.7](https://www.python.org/download/releases/2.7)
|
|
||||||
- [Moulinette](https://github.com/YunoHost/moulinette)
|
|
||||||
- [Bash](https://www.gnu.org/software/bash/bash.html)
|
|
||||||
- [Debian Stretch](https://www.debian.org/releases/stretch)
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
As [other components of YunoHost core code](https://yunohost.org/#/faq_en), this repository is licensed GNU AGPL v3.
|
As [other components of YunoHost](https://yunohost.org/#/faq_en), this repository is licensed under GNU AGPL v3.
|
||||||
|
|
|
@ -179,6 +179,10 @@ def _retrieve_namespaces():
|
||||||
ret.append(n)
|
ret.append(n)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
# Stupid PATH management because sometimes (e.g. some cron job) PATH is only /usr/bin:/bin ...
|
||||||
|
default_path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
if os.environ["PATH"] != default_path:
|
||||||
|
os.environ["PATH"] = default_path + ":" + os.environ["PATH"]
|
||||||
|
|
||||||
# Main action ----------------------------------------------------------
|
# Main action ----------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -201,24 +201,34 @@ user:
|
||||||
|
|
||||||
subcategories:
|
subcategories:
|
||||||
group:
|
group:
|
||||||
subcategory_help: Manage group
|
subcategory_help: Manage user groups
|
||||||
actions:
|
actions:
|
||||||
### user_group_list()
|
### user_group_list()
|
||||||
list:
|
list:
|
||||||
action_help: List group
|
action_help: List existing groups
|
||||||
api: GET /users/groups
|
api: GET /users/groups
|
||||||
arguments:
|
arguments:
|
||||||
--fields:
|
-s:
|
||||||
help: fields to fetch
|
full: --short
|
||||||
nargs: "+"
|
help: List only the names of groups
|
||||||
|
action: store_true
|
||||||
|
-f:
|
||||||
|
full: --full
|
||||||
|
help: Display all informations known about each groups
|
||||||
|
action: store_true
|
||||||
|
-p:
|
||||||
|
full: --include-primary-groups
|
||||||
|
help: Also display primary groups (each user has an eponym group that only contains itself)
|
||||||
|
action: store_true
|
||||||
|
default: false
|
||||||
|
|
||||||
### user_group_add()
|
### user_group_create()
|
||||||
add:
|
create:
|
||||||
action_help: Create group
|
action_help: Create group
|
||||||
api: POST /users/groups
|
api: POST /users/groups
|
||||||
arguments:
|
arguments:
|
||||||
groupname:
|
groupname:
|
||||||
help: The unique group name to add
|
help: Name of the group to be created
|
||||||
extra:
|
extra:
|
||||||
pattern: &pattern_groupname
|
pattern: &pattern_groupname
|
||||||
- !!str ^[a-z0-9_]+$
|
- !!str ^[a-z0-9_]+$
|
||||||
|
@ -230,7 +240,7 @@ user:
|
||||||
api: DELETE /users/groups/<groupname>
|
api: DELETE /users/groups/<groupname>
|
||||||
arguments:
|
arguments:
|
||||||
groupname:
|
groupname:
|
||||||
help: Username to delete
|
help: Name of the group to be deleted
|
||||||
extra:
|
extra:
|
||||||
pattern: *pattern_groupname
|
pattern: *pattern_groupname
|
||||||
|
|
||||||
|
@ -240,19 +250,19 @@ user:
|
||||||
api: PUT /users/groups/<groupname>
|
api: PUT /users/groups/<groupname>
|
||||||
arguments:
|
arguments:
|
||||||
groupname:
|
groupname:
|
||||||
help: Username to update
|
help: Name of the group to be updated
|
||||||
extra:
|
extra:
|
||||||
pattern: *pattern_groupname
|
pattern: *pattern_groupname
|
||||||
-a:
|
-a:
|
||||||
full: --add-user
|
full: --add
|
||||||
help: User to add in group
|
help: User(s) to add in the group
|
||||||
nargs: "*"
|
nargs: "*"
|
||||||
metavar: USERNAME
|
metavar: USERNAME
|
||||||
extra:
|
extra:
|
||||||
pattern: *pattern_username
|
pattern: *pattern_username
|
||||||
-r:
|
-r:
|
||||||
full: --remove-user
|
full: --remove
|
||||||
help: User to remove in group
|
help: User(s) to remove in the group
|
||||||
nargs: "*"
|
nargs: "*"
|
||||||
metavar: USERNAME
|
metavar: USERNAME
|
||||||
extra:
|
extra:
|
||||||
|
@ -260,112 +270,69 @@ user:
|
||||||
|
|
||||||
### user_group_info()
|
### user_group_info()
|
||||||
info:
|
info:
|
||||||
action_help: Get group information
|
action_help: Get information about a specific group
|
||||||
api: GET /users/groups/<groupname>
|
api: GET /users/groups/<groupname>
|
||||||
arguments:
|
arguments:
|
||||||
groupname:
|
groupname:
|
||||||
help: Groupname to get information
|
help: Name of the group to fetch info about
|
||||||
extra:
|
extra:
|
||||||
pattern: *pattern_username
|
pattern: *pattern_username
|
||||||
|
|
||||||
permission:
|
permission:
|
||||||
subcategory_help: Manage user permission
|
subcategory_help: Manage permissions
|
||||||
actions:
|
actions:
|
||||||
|
|
||||||
### user_permission_list()
|
### user_permission_list()
|
||||||
list:
|
list:
|
||||||
action_help: List access to user and group
|
action_help: List permissions and corresponding accesses
|
||||||
api: GET /users/permissions/<app>
|
api: GET /users/permissions
|
||||||
arguments:
|
arguments:
|
||||||
|
-s:
|
||||||
|
full: --short
|
||||||
|
help: Only list permission names
|
||||||
|
action: store_true
|
||||||
|
-f:
|
||||||
|
full: --full
|
||||||
|
help: Display all info known about each permission, including the full user list of each group it is granted to.
|
||||||
|
action: store_true
|
||||||
|
|
||||||
|
### user_permission_info()
|
||||||
|
info:
|
||||||
|
action_help: Get information about a specific permission
|
||||||
|
api: GET /users/permissions/<permission>
|
||||||
|
arguments:
|
||||||
|
permission:
|
||||||
|
help: Name of the permission to fetch info about
|
||||||
|
|
||||||
|
### user_permission_update()
|
||||||
|
update:
|
||||||
|
action_help: Manage group or user permissions
|
||||||
|
api: PUT /users/permissions/<permission>
|
||||||
|
arguments:
|
||||||
|
permission:
|
||||||
|
help: Permission to manage (e.g. mail or nextcloud or wordpress.editors)
|
||||||
-a:
|
-a:
|
||||||
full: --app
|
full: --add
|
||||||
help: Application to manage the permission
|
help: Group or usernames to grant this permission to
|
||||||
nargs: "*"
|
nargs: "*"
|
||||||
metavar: APP
|
metavar: GROUP_OR_USER
|
||||||
-p:
|
|
||||||
full: --permission
|
|
||||||
help: Name of permission (main by default)
|
|
||||||
nargs: "*"
|
|
||||||
metavar: PERMISSION
|
|
||||||
-u:
|
|
||||||
full: --username
|
|
||||||
help: Username
|
|
||||||
nargs: "*"
|
|
||||||
metavar: USER
|
|
||||||
-g:
|
|
||||||
full: --group
|
|
||||||
help: Group name
|
|
||||||
nargs: "*"
|
|
||||||
metavar: GROUP
|
|
||||||
|
|
||||||
### user_permission_add()
|
|
||||||
add:
|
|
||||||
action_help: Grant access right to users and group
|
|
||||||
api: POST /users/permissions/<app>
|
|
||||||
arguments:
|
|
||||||
app:
|
|
||||||
help: Application to manage the permission
|
|
||||||
nargs: "+"
|
|
||||||
-p:
|
|
||||||
full: --permission
|
|
||||||
help: Name of permission (main by default)
|
|
||||||
nargs: "*"
|
|
||||||
metavar: PERMISSION
|
|
||||||
-u:
|
|
||||||
full: --username
|
|
||||||
help: Username
|
|
||||||
nargs: "*"
|
|
||||||
metavar: USER
|
|
||||||
extra:
|
extra:
|
||||||
pattern: *pattern_username
|
pattern: *pattern_username
|
||||||
-g:
|
-r:
|
||||||
full: --group
|
full: --remove
|
||||||
help: Group name
|
help: Group or usernames revoke this permission from
|
||||||
nargs: "*"
|
nargs: "*"
|
||||||
metavar: GROUP
|
metavar: GROUP_OR_USER
|
||||||
extra:
|
extra:
|
||||||
pattern: *pattern_username
|
pattern: *pattern_username
|
||||||
|
|
||||||
### user_permission_remove()
|
## user_permission_reset()
|
||||||
remove:
|
reset:
|
||||||
action_help: Revoke access right to users and group
|
action_help: Reset allowed groups to the default (all_users) for a given permission
|
||||||
api: PUT /users/permissions/<app>
|
|
||||||
arguments:
|
|
||||||
app:
|
|
||||||
help: Application to manage the permission
|
|
||||||
nargs: "+"
|
|
||||||
-p:
|
|
||||||
full: --permission
|
|
||||||
help: Name of permission (main by default)
|
|
||||||
nargs: "*"
|
|
||||||
metavar: PERMISSION
|
|
||||||
-u:
|
|
||||||
full: --username
|
|
||||||
help: Username
|
|
||||||
nargs: "*"
|
|
||||||
metavar: USER
|
|
||||||
extra:
|
|
||||||
pattern: *pattern_username
|
|
||||||
-g:
|
|
||||||
full: --group
|
|
||||||
help: Group name
|
|
||||||
nargs: "*"
|
|
||||||
metavar: GROUP
|
|
||||||
extra:
|
|
||||||
pattern: *pattern_username
|
|
||||||
|
|
||||||
## user_permission_clear()
|
|
||||||
clear:
|
|
||||||
action_help: Reset access rights for the app
|
|
||||||
api: DELETE /users/permissions/<app>
|
api: DELETE /users/permissions/<app>
|
||||||
arguments:
|
arguments:
|
||||||
app:
|
permission:
|
||||||
help: Application to manage the permission
|
help: Permission to manage (e.g. mail or nextcloud or wordpress.editors)
|
||||||
nargs: "+"
|
|
||||||
-p:
|
|
||||||
full: --permission
|
|
||||||
help: Name of permission (main by default)
|
|
||||||
nargs: "*"
|
|
||||||
metavar: PERMISSION
|
|
||||||
|
|
||||||
ssh:
|
ssh:
|
||||||
subcategory_help: Manage ssh access
|
subcategory_help: Manage ssh access
|
||||||
|
@ -439,6 +406,10 @@ domain:
|
||||||
list:
|
list:
|
||||||
action_help: List domains
|
action_help: List domains
|
||||||
api: GET /domains
|
api: GET /domains
|
||||||
|
arguments:
|
||||||
|
--exclude-subdomains:
|
||||||
|
help: Filter out domains that are obviously subdomains of other declared domains
|
||||||
|
action: store_true
|
||||||
|
|
||||||
### domain_add()
|
### domain_add()
|
||||||
add:
|
add:
|
||||||
|
@ -481,6 +452,21 @@ domain:
|
||||||
- !!str ^[0-9]+$
|
- !!str ^[0-9]+$
|
||||||
- "pattern_positive_number"
|
- "pattern_positive_number"
|
||||||
|
|
||||||
|
### domain_maindomain()
|
||||||
|
main-domain:
|
||||||
|
action_help: Check the current main domain, or change it
|
||||||
|
deprecated_alias:
|
||||||
|
- maindomain
|
||||||
|
api:
|
||||||
|
- GET /domains/main
|
||||||
|
- PUT /domains/main
|
||||||
|
arguments:
|
||||||
|
-n:
|
||||||
|
full: --new-main-domain
|
||||||
|
help: Change the current main domain
|
||||||
|
extra:
|
||||||
|
pattern: *pattern_domain
|
||||||
|
|
||||||
### certificate_status()
|
### certificate_status()
|
||||||
cert-status:
|
cert-status:
|
||||||
action_help: List status of current certificates (all by default).
|
action_help: List status of current certificates (all by default).
|
||||||
|
@ -568,78 +554,53 @@ app:
|
||||||
category_help: Manage apps
|
category_help: Manage apps
|
||||||
actions:
|
actions:
|
||||||
|
|
||||||
### app_fetchlist()
|
catalog:
|
||||||
|
action_help: Show the catalog of installable application
|
||||||
|
api: GET /appscatalog
|
||||||
|
arguments:
|
||||||
|
-f:
|
||||||
|
full: --full
|
||||||
|
help: Display all details, including the app manifest and various other infos
|
||||||
|
action: store_true
|
||||||
|
-c:
|
||||||
|
full: --with-categories
|
||||||
|
help: Also return a list of app categories
|
||||||
|
action: store_true
|
||||||
|
|
||||||
fetchlist:
|
fetchlist:
|
||||||
action_help: Fetch application lists from app servers, or register a new one.
|
deprecated: true
|
||||||
api: PUT /appslists
|
|
||||||
arguments:
|
|
||||||
-n:
|
|
||||||
full: --name
|
|
||||||
help: Name of the list to fetch (fetches all registered lists if empty)
|
|
||||||
extra:
|
|
||||||
pattern: &pattern_listname
|
|
||||||
- !!str ^[a-z0-9_]+$
|
|
||||||
- "pattern_listname"
|
|
||||||
-u:
|
|
||||||
full: --url
|
|
||||||
help: URL of a new application list to register. To be specified with -n.
|
|
||||||
|
|
||||||
### app_listlists()
|
|
||||||
listlists:
|
|
||||||
action_help: List registered application lists
|
|
||||||
api: GET /appslists
|
|
||||||
|
|
||||||
### app_removelist()
|
|
||||||
removelist:
|
|
||||||
action_help: Remove and forget about a given application list
|
|
||||||
api: DELETE /appslists
|
|
||||||
arguments:
|
|
||||||
name:
|
|
||||||
help: Name of the list to remove
|
|
||||||
extra:
|
|
||||||
ask: ask_list_to_remove
|
|
||||||
pattern: *pattern_listname
|
|
||||||
|
|
||||||
### app_list()
|
### app_list()
|
||||||
list:
|
list:
|
||||||
action_help: List apps
|
action_help: List installed apps
|
||||||
api: GET /apps
|
api: GET /apps
|
||||||
arguments:
|
arguments:
|
||||||
-f:
|
-f:
|
||||||
full: --filter
|
full: --full
|
||||||
help: Name filter of app_id or app_name
|
help: Display all details, including the app manifest and various other infos
|
||||||
-r:
|
|
||||||
full: --raw
|
|
||||||
help: Return the full app_dict
|
|
||||||
action: store_true
|
action: store_true
|
||||||
-i:
|
-i:
|
||||||
full: --installed
|
full: --installed
|
||||||
help: Return only installed apps
|
help: Dummy argument, does nothing anymore (still there only for backward compatibility)
|
||||||
action: store_true
|
|
||||||
-b:
|
|
||||||
full: --with-backup
|
|
||||||
help: Return only apps with backup feature (force --installed filter)
|
|
||||||
action: store_true
|
action: store_true
|
||||||
|
filter:
|
||||||
|
nargs: '?'
|
||||||
|
|
||||||
### app_info()
|
### app_info()
|
||||||
info:
|
info:
|
||||||
action_help: Get information about an installed app
|
action_help: Show infos about a specific installed app
|
||||||
api: GET /apps/<app>
|
api: GET /apps/<app>
|
||||||
arguments:
|
arguments:
|
||||||
app:
|
app:
|
||||||
help: Specific app ID
|
help: Specific app ID
|
||||||
-s:
|
-f:
|
||||||
full: --show-status
|
full: --full
|
||||||
help: Show app installation status
|
help: Display all details, including the app manifest and various other infos
|
||||||
action: store_true
|
|
||||||
-r:
|
|
||||||
full: --raw
|
|
||||||
help: Return the full app_dict
|
|
||||||
action: store_true
|
action: store_true
|
||||||
|
|
||||||
### app_map()
|
### app_map()
|
||||||
map:
|
map:
|
||||||
action_help: List apps by domain
|
action_help: Show the mapping between urls and apps
|
||||||
api: GET /appsmap
|
api: GET /appsmap
|
||||||
arguments:
|
arguments:
|
||||||
-a:
|
-a:
|
||||||
|
@ -738,30 +699,6 @@ app:
|
||||||
help: Delete the key
|
help: Delete the key
|
||||||
action: store_true
|
action: store_true
|
||||||
|
|
||||||
### app_checkport()
|
|
||||||
checkport:
|
|
||||||
action_help: Check availability of a local port
|
|
||||||
api: GET /tools/checkport
|
|
||||||
deprecated: true
|
|
||||||
arguments:
|
|
||||||
port:
|
|
||||||
help: Port to check
|
|
||||||
extra:
|
|
||||||
pattern: &pattern_port
|
|
||||||
- !!str ^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
|
|
||||||
- "pattern_port"
|
|
||||||
|
|
||||||
### app_checkurl()
|
|
||||||
checkurl:
|
|
||||||
action_help: Check availability of a web path
|
|
||||||
api: GET /tools/checkurl
|
|
||||||
deprecated: True
|
|
||||||
arguments:
|
|
||||||
url:
|
|
||||||
help: Url to check
|
|
||||||
-a:
|
|
||||||
full: --app
|
|
||||||
help: Write domain & path to app settings for further checks
|
|
||||||
|
|
||||||
### app_register_url()
|
### app_register_url()
|
||||||
register-url:
|
register-url:
|
||||||
|
@ -776,32 +713,6 @@ app:
|
||||||
help: The path to be registered (e.g. /coffee)
|
help: The path to be registered (e.g. /coffee)
|
||||||
|
|
||||||
|
|
||||||
### app_initdb()
|
|
||||||
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
|
|
||||||
-p:
|
|
||||||
full: --password
|
|
||||||
help: Password of the DB (generated unless set)
|
|
||||||
-d:
|
|
||||||
full: --db
|
|
||||||
help: DB name (user unless set)
|
|
||||||
-s:
|
|
||||||
full: --sql
|
|
||||||
help: Initial SQL file
|
|
||||||
|
|
||||||
### app_debug()
|
|
||||||
debug:
|
|
||||||
action_help: Display all debug informations for an application
|
|
||||||
api: GET /apps/<app>/debug
|
|
||||||
arguments:
|
|
||||||
app:
|
|
||||||
help: App name
|
|
||||||
|
|
||||||
### app_makedefault()
|
### app_makedefault()
|
||||||
makedefault:
|
makedefault:
|
||||||
action_help: Redirect domain root to an app
|
action_help: Redirect domain root to an app
|
||||||
|
@ -832,6 +743,7 @@ app:
|
||||||
addaccess:
|
addaccess:
|
||||||
action_help: Grant access right to users (everyone by default)
|
action_help: Grant access right to users (everyone by default)
|
||||||
api: PUT /access
|
api: PUT /access
|
||||||
|
deprecated: true
|
||||||
arguments:
|
arguments:
|
||||||
apps:
|
apps:
|
||||||
nargs: "+"
|
nargs: "+"
|
||||||
|
@ -843,6 +755,7 @@ app:
|
||||||
removeaccess:
|
removeaccess:
|
||||||
action_help: Revoke access right to users (everyone by default)
|
action_help: Revoke access right to users (everyone by default)
|
||||||
api: DELETE /access
|
api: DELETE /access
|
||||||
|
deprecated: true
|
||||||
arguments:
|
arguments:
|
||||||
apps:
|
apps:
|
||||||
nargs: "+"
|
nargs: "+"
|
||||||
|
@ -854,6 +767,7 @@ app:
|
||||||
clearaccess:
|
clearaccess:
|
||||||
action_help: Reset access rights for the app
|
action_help: Reset access rights for the app
|
||||||
api: POST /access
|
api: POST /access
|
||||||
|
deprecated: true
|
||||||
arguments:
|
arguments:
|
||||||
apps:
|
apps:
|
||||||
nargs: "+"
|
nargs: "+"
|
||||||
|
@ -1005,147 +919,6 @@ backup:
|
||||||
pattern: *pattern_backup_archive_name
|
pattern: *pattern_backup_archive_name
|
||||||
|
|
||||||
|
|
||||||
#############################
|
|
||||||
# Monitor #
|
|
||||||
#############################
|
|
||||||
monitor:
|
|
||||||
category_help: Monitor the server
|
|
||||||
actions:
|
|
||||||
|
|
||||||
### monitor_disk()
|
|
||||||
disk:
|
|
||||||
action_help: Monitor disk space and usage
|
|
||||||
api: GET /monitor/disk
|
|
||||||
arguments:
|
|
||||||
-f:
|
|
||||||
full: --filesystem
|
|
||||||
help: Show filesystem disk space
|
|
||||||
action: append_const
|
|
||||||
const: filesystem
|
|
||||||
dest: units
|
|
||||||
-t:
|
|
||||||
full: --io
|
|
||||||
help: Show I/O throughput
|
|
||||||
action: append_const
|
|
||||||
const: io
|
|
||||||
dest: units
|
|
||||||
-m:
|
|
||||||
full: --mountpoint
|
|
||||||
help: Monitor only the device mounted on MOUNTPOINT
|
|
||||||
action: store
|
|
||||||
-H:
|
|
||||||
full: --human-readable
|
|
||||||
help: Print sizes in human readable format
|
|
||||||
action: store_true
|
|
||||||
|
|
||||||
### monitor_network()
|
|
||||||
network:
|
|
||||||
action_help: Monitor network interfaces
|
|
||||||
api: GET /monitor/network
|
|
||||||
arguments:
|
|
||||||
-u:
|
|
||||||
full: --usage
|
|
||||||
help: Show interfaces bit rates
|
|
||||||
action: append_const
|
|
||||||
const: usage
|
|
||||||
dest: units
|
|
||||||
-i:
|
|
||||||
full: --infos
|
|
||||||
help: Show network informations
|
|
||||||
action: append_const
|
|
||||||
const: infos
|
|
||||||
dest: units
|
|
||||||
-c:
|
|
||||||
full: --check
|
|
||||||
help: Check network configuration
|
|
||||||
action: append_const
|
|
||||||
const: check
|
|
||||||
dest: units
|
|
||||||
-H:
|
|
||||||
full: --human-readable
|
|
||||||
help: Print sizes in human readable format
|
|
||||||
action: store_true
|
|
||||||
|
|
||||||
### monitor_system()
|
|
||||||
system:
|
|
||||||
action_help: Monitor system informations and usage
|
|
||||||
api: GET /monitor/system
|
|
||||||
arguments:
|
|
||||||
-m:
|
|
||||||
full: --memory
|
|
||||||
help: Show memory usage
|
|
||||||
action: append_const
|
|
||||||
const: memory
|
|
||||||
dest: units
|
|
||||||
-c:
|
|
||||||
full: --cpu
|
|
||||||
help: Show CPU usage and load
|
|
||||||
action: append_const
|
|
||||||
const: cpu
|
|
||||||
dest: units
|
|
||||||
-p:
|
|
||||||
full: --process
|
|
||||||
help: Show processes summary
|
|
||||||
action: append_const
|
|
||||||
const: process
|
|
||||||
dest: units
|
|
||||||
-u:
|
|
||||||
full: --uptime
|
|
||||||
help: Show the system uptime
|
|
||||||
action: append_const
|
|
||||||
const: uptime
|
|
||||||
dest: units
|
|
||||||
-i:
|
|
||||||
full: --infos
|
|
||||||
help: Show system informations
|
|
||||||
action: append_const
|
|
||||||
const: infos
|
|
||||||
dest: units
|
|
||||||
-H:
|
|
||||||
full: --human-readable
|
|
||||||
help: Print sizes in human readable format
|
|
||||||
action: store_true
|
|
||||||
|
|
||||||
### monitor_updatestats()
|
|
||||||
update-stats:
|
|
||||||
action_help: Update monitoring statistics
|
|
||||||
api: POST /monitor/stats
|
|
||||||
arguments:
|
|
||||||
period:
|
|
||||||
help: Time period to update
|
|
||||||
choices:
|
|
||||||
- day
|
|
||||||
- week
|
|
||||||
- month
|
|
||||||
|
|
||||||
### monitor_showstats()
|
|
||||||
show-stats:
|
|
||||||
action_help: Show monitoring statistics
|
|
||||||
api: GET /monitor/stats
|
|
||||||
arguments:
|
|
||||||
period:
|
|
||||||
help: Time period to show
|
|
||||||
choices:
|
|
||||||
- day
|
|
||||||
- week
|
|
||||||
- month
|
|
||||||
|
|
||||||
### monitor_enable()
|
|
||||||
enable:
|
|
||||||
action_help: Enable server monitoring
|
|
||||||
api: PUT /monitor
|
|
||||||
arguments:
|
|
||||||
-s:
|
|
||||||
full: --with-stats
|
|
||||||
help: Enable monitoring statistics
|
|
||||||
action: store_true
|
|
||||||
|
|
||||||
### monitor_disable()
|
|
||||||
disable:
|
|
||||||
api: DELETE /monitor
|
|
||||||
action_help: Disable server monitoring
|
|
||||||
|
|
||||||
|
|
||||||
#############################
|
#############################
|
||||||
# Settings #
|
# Settings #
|
||||||
#############################
|
#############################
|
||||||
|
@ -1209,24 +982,13 @@ service:
|
||||||
arguments:
|
arguments:
|
||||||
name:
|
name:
|
||||||
help: Service name to add
|
help: Service name to add
|
||||||
-s:
|
-d:
|
||||||
full: --status
|
full: --description
|
||||||
help: Custom status command
|
help: Description of the service
|
||||||
-l:
|
-l:
|
||||||
full: --log
|
full: --log
|
||||||
help: Absolute path to log file to display
|
help: Absolute path to log file to display
|
||||||
nargs: "+"
|
nargs: "+"
|
||||||
-r:
|
|
||||||
full: --runlevel
|
|
||||||
help: Runlevel priority of the service
|
|
||||||
type: int
|
|
||||||
-n:
|
|
||||||
full: --need_lock
|
|
||||||
help: Use this option to prevent deadlocks if the service does invoke yunohost commands.
|
|
||||||
action: store_true
|
|
||||||
-d:
|
|
||||||
full: --description
|
|
||||||
help: Description of the service
|
|
||||||
-t:
|
-t:
|
||||||
full: --log_type
|
full: --log_type
|
||||||
help: Type of the log (file or systemd)
|
help: Type of the log (file or systemd)
|
||||||
|
@ -1235,6 +997,22 @@ service:
|
||||||
- file
|
- file
|
||||||
- systemd
|
- systemd
|
||||||
default: file
|
default: file
|
||||||
|
--test_status:
|
||||||
|
help: Specify a custom bash command to check the status of the service. Note that it only makes sense to specify this if the corresponding systemd service does not return the proper information already.
|
||||||
|
--test_conf:
|
||||||
|
help: Specify a custom bash command to check if the configuration of the service is valid or broken, similar to nginx -t.
|
||||||
|
--needs_exposed_ports:
|
||||||
|
help: A list of ports that needs to be publicly exposed for the service to work as intended.
|
||||||
|
nargs: "+"
|
||||||
|
type: int
|
||||||
|
metavar: PORT
|
||||||
|
-n:
|
||||||
|
full: --need_lock
|
||||||
|
help: Use this option to prevent deadlocks if the service does invoke yunohost commands.
|
||||||
|
action: store_true
|
||||||
|
-s:
|
||||||
|
full: --status
|
||||||
|
help: Deprecated, old option. Does nothing anymore. Possibly check the --test_status option.
|
||||||
|
|
||||||
### service_remove()
|
### service_remove()
|
||||||
remove:
|
remove:
|
||||||
|
@ -1276,6 +1054,7 @@ service:
|
||||||
### service_restart()
|
### service_restart()
|
||||||
restart:
|
restart:
|
||||||
action_help: Restart one or more services. If the services are not running yet, they will be started.
|
action_help: Restart one or more services. If the services are not running yet, they will be started.
|
||||||
|
api: PUT /services/<names>/restart
|
||||||
arguments:
|
arguments:
|
||||||
names:
|
names:
|
||||||
help: Service name to restart
|
help: Service name to restart
|
||||||
|
@ -1579,12 +1358,9 @@ tools:
|
||||||
### tools_maindomain()
|
### tools_maindomain()
|
||||||
maindomain:
|
maindomain:
|
||||||
action_help: Check the current main domain, or change it
|
action_help: Check the current main domain, or change it
|
||||||
api:
|
|
||||||
- GET /domains/main
|
|
||||||
- PUT /domains/main
|
|
||||||
arguments:
|
arguments:
|
||||||
-n:
|
-n:
|
||||||
full: --new-domain
|
full: --new-main-domain
|
||||||
help: Change the current main domain
|
help: Change the current main domain
|
||||||
extra:
|
extra:
|
||||||
pattern: *pattern_domain
|
pattern: *pattern_domain
|
||||||
|
@ -1643,26 +1419,6 @@ tools:
|
||||||
help: Upgrade only the system packages
|
help: Upgrade only the system packages
|
||||||
action: store_true
|
action: store_true
|
||||||
|
|
||||||
### tools_diagnosis()
|
|
||||||
diagnosis:
|
|
||||||
action_help: YunoHost diagnosis
|
|
||||||
api: GET /diagnosis
|
|
||||||
arguments:
|
|
||||||
-p:
|
|
||||||
full: --private
|
|
||||||
help: Show private data (domain, IP)
|
|
||||||
action: store_true
|
|
||||||
|
|
||||||
### tools_port_available()
|
|
||||||
port-available:
|
|
||||||
action_help: Check availability of a local port
|
|
||||||
api: GET /tools/portavailable
|
|
||||||
arguments:
|
|
||||||
port:
|
|
||||||
help: Port to check
|
|
||||||
extra:
|
|
||||||
pattern: *pattern_port
|
|
||||||
|
|
||||||
### tools_shell()
|
### tools_shell()
|
||||||
shell:
|
shell:
|
||||||
action_help: Launch a development shell
|
action_help: Launch a development shell
|
||||||
|
@ -1717,6 +1473,11 @@ tools:
|
||||||
help: List pending configuration files and exit
|
help: List pending configuration files and exit
|
||||||
action: store_true
|
action: store_true
|
||||||
|
|
||||||
|
### tools_versions()
|
||||||
|
versions:
|
||||||
|
action_help: Display YunoHost's packages versions
|
||||||
|
api: GET /versions
|
||||||
|
|
||||||
subcategories:
|
subcategories:
|
||||||
|
|
||||||
migrations:
|
migrations:
|
||||||
|
@ -1872,7 +1633,7 @@ log:
|
||||||
api: GET /logs
|
api: GET /logs
|
||||||
arguments:
|
arguments:
|
||||||
category:
|
category:
|
||||||
help: Log category to display (default operations), could be operation, history, package, system, access, service or app
|
help: Log category to display (default operations), could be operation, history, package, system, access, service or app
|
||||||
nargs: "*"
|
nargs: "*"
|
||||||
-l:
|
-l:
|
||||||
full: --limit
|
full: --limit
|
||||||
|
@ -1898,3 +1659,73 @@ log:
|
||||||
--share:
|
--share:
|
||||||
help: Share the full log using yunopaste
|
help: Share the full log using yunopaste
|
||||||
action: store_true
|
action: store_true
|
||||||
|
|
||||||
|
|
||||||
|
#############################
|
||||||
|
# Diagnosis #
|
||||||
|
#############################
|
||||||
|
diagnosis:
|
||||||
|
category_help: Look for possible issues on the server
|
||||||
|
actions:
|
||||||
|
|
||||||
|
list:
|
||||||
|
action_help: List diagnosis categories
|
||||||
|
api: GET /diagnosis/list
|
||||||
|
|
||||||
|
show:
|
||||||
|
action_help: Show most recents diagnosis results
|
||||||
|
api: GET /diagnosis/show
|
||||||
|
arguments:
|
||||||
|
categories:
|
||||||
|
help: Diagnosis categories to display (all by default)
|
||||||
|
nargs: "*"
|
||||||
|
--full:
|
||||||
|
help: Display additional information
|
||||||
|
action: store_true
|
||||||
|
--issues:
|
||||||
|
help: Only display issues
|
||||||
|
action: store_true
|
||||||
|
--share:
|
||||||
|
help: Share the logs using yunopaste
|
||||||
|
action: store_true
|
||||||
|
|
||||||
|
run:
|
||||||
|
action_help: Run diagnosis
|
||||||
|
api: POST /diagnosis/run
|
||||||
|
arguments:
|
||||||
|
categories:
|
||||||
|
help: Diagnosis categories to run (all by default)
|
||||||
|
nargs: "*"
|
||||||
|
--force:
|
||||||
|
help: Ignore the cached report even if it is still 'fresh'
|
||||||
|
action: store_true
|
||||||
|
--except-if-never-ran-yet:
|
||||||
|
help: Don't run anything if diagnosis never ran yet ... (this is meant to be used by the webadmin)
|
||||||
|
action: store_true
|
||||||
|
|
||||||
|
ignore:
|
||||||
|
action_help: Configure some diagnosis results to be ignored and therefore not considered as actual issues
|
||||||
|
api: POST /diagnosis/ignore
|
||||||
|
arguments:
|
||||||
|
--add-filter:
|
||||||
|
help: "Add a filter. The first element should be a diagnosis category, and other criterias can be provided using the infos from the 'meta' sections in 'yunohost diagnosis show'. For example: 'dnsrecords domain=yolo.test category=xmpp'"
|
||||||
|
nargs: "*"
|
||||||
|
metavar: CRITERIA
|
||||||
|
--remove-filter:
|
||||||
|
help: Remove a filter (it should be an existing filter as listed with --list)
|
||||||
|
nargs: "*"
|
||||||
|
metavar: CRITERIA
|
||||||
|
--list:
|
||||||
|
help: List active ignore filters
|
||||||
|
action: store_true
|
||||||
|
|
||||||
|
get:
|
||||||
|
action_help: Low-level command to fetch raw data and status about a specific diagnosis test
|
||||||
|
api: GET /diagnosis/item/<category>
|
||||||
|
arguments:
|
||||||
|
category:
|
||||||
|
help: Diagnosis category to fetch results from
|
||||||
|
item:
|
||||||
|
help: "List of criteria describing the test. Must correspond exactly to the 'meta' infos in 'yunohost diagnosis show'"
|
||||||
|
metavar: CRITERIA
|
||||||
|
nargs: "*"
|
||||||
|
|
|
@ -3,7 +3,7 @@ Simple automated generation of a bash_completion file
|
||||||
for yunohost command from the actionsmap.
|
for yunohost command from the actionsmap.
|
||||||
|
|
||||||
Generates a bash completion file assuming the structure
|
Generates a bash completion file assuming the structure
|
||||||
`yunohost domain action`
|
`yunohost category action`
|
||||||
adds `--help` at the end if one presses [tab] again.
|
adds `--help` at the end if one presses [tab] again.
|
||||||
|
|
||||||
author: Christophe Vuillot
|
author: Christophe Vuillot
|
||||||
|
@ -15,18 +15,39 @@ THIS_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
ACTIONSMAP_FILE = THIS_SCRIPT_DIR + '/yunohost.yml'
|
ACTIONSMAP_FILE = THIS_SCRIPT_DIR + '/yunohost.yml'
|
||||||
BASH_COMPLETION_FILE = THIS_SCRIPT_DIR + '/../bash-completion.d/yunohost'
|
BASH_COMPLETION_FILE = THIS_SCRIPT_DIR + '/../bash-completion.d/yunohost'
|
||||||
|
|
||||||
|
def get_dict_actions(OPTION_SUBTREE, category):
|
||||||
|
ACTIONS = [action for action in OPTION_SUBTREE[category]["actions"].keys()
|
||||||
|
if not action.startswith('_')]
|
||||||
|
ACTIONS_STR = '{}'.format(' '.join(ACTIONS))
|
||||||
|
|
||||||
|
DICT = { "actions_str": ACTIONS_STR }
|
||||||
|
|
||||||
|
return DICT
|
||||||
|
|
||||||
with open(ACTIONSMAP_FILE, 'r') as stream:
|
with open(ACTIONSMAP_FILE, 'r') as stream:
|
||||||
|
|
||||||
# Getting the dictionary containning what actions are possible per domain
|
# Getting the dictionary containning what actions are possible per category
|
||||||
OPTION_TREE = yaml.load(stream)
|
OPTION_TREE = yaml.load(stream)
|
||||||
DOMAINS = [str for str in OPTION_TREE.keys() if not str.startswith('_')]
|
|
||||||
DOMAINS_STR = '"{}"'.format(' '.join(DOMAINS))
|
CATEGORY = [category for category in OPTION_TREE.keys() if not category.startswith('_')]
|
||||||
|
|
||||||
|
CATEGORY_STR = '{}'.format(' '.join(CATEGORY))
|
||||||
ACTIONS_DICT = {}
|
ACTIONS_DICT = {}
|
||||||
for domain in DOMAINS:
|
for category in CATEGORY:
|
||||||
ACTIONS = [str for str in OPTION_TREE[domain]['actions'].keys()
|
ACTIONS_DICT[category] = get_dict_actions(OPTION_TREE, category)
|
||||||
if not str.startswith('_')]
|
|
||||||
ACTIONS_STR = '"{}"'.format(' '.join(ACTIONS))
|
ACTIONS_DICT[category]["subcategories"] = {}
|
||||||
ACTIONS_DICT[domain] = ACTIONS_STR
|
ACTIONS_DICT[category]["subcategories_str"] = ""
|
||||||
|
|
||||||
|
if "subcategories" in OPTION_TREE[category].keys():
|
||||||
|
SUBCATEGORIES = [ subcategory for subcategory in OPTION_TREE[category]["subcategories"].keys() ]
|
||||||
|
|
||||||
|
SUBCATEGORIES_STR = '{}'.format(' '.join(SUBCATEGORIES))
|
||||||
|
|
||||||
|
ACTIONS_DICT[category]["subcategories_str"] = SUBCATEGORIES_STR
|
||||||
|
|
||||||
|
for subcategory in SUBCATEGORIES:
|
||||||
|
ACTIONS_DICT[category]["subcategories"][subcategory] = get_dict_actions(OPTION_TREE[category]["subcategories"], subcategory)
|
||||||
|
|
||||||
with open(BASH_COMPLETION_FILE, 'w') as generated_file:
|
with open(BASH_COMPLETION_FILE, 'w') as generated_file:
|
||||||
|
|
||||||
|
@ -47,31 +68,49 @@ with open(ACTIONSMAP_FILE, 'r') as stream:
|
||||||
generated_file.write('\tnarg=${#COMP_WORDS[@]}\n\n')
|
generated_file.write('\tnarg=${#COMP_WORDS[@]}\n\n')
|
||||||
generated_file.write('\t# the current word being typed\n')
|
generated_file.write('\t# the current word being typed\n')
|
||||||
generated_file.write('\tcur="${COMP_WORDS[COMP_CWORD]}"\n\n')
|
generated_file.write('\tcur="${COMP_WORDS[COMP_CWORD]}"\n\n')
|
||||||
generated_file.write('\t# the last typed word\n')
|
|
||||||
generated_file.write('\tprev="${COMP_WORDS[COMP_CWORD-1]}"\n\n')
|
|
||||||
|
|
||||||
# If one is currently typing a domain then match with the domain list
|
# If one is currently typing a category then match with the category list
|
||||||
generated_file.write('\t# If one is currently typing a domain,\n')
|
generated_file.write('\t# If one is currently typing a category,\n')
|
||||||
generated_file.write('\t# match with domains\n')
|
generated_file.write('\t# match with categorys\n')
|
||||||
generated_file.write('\tif [[ $narg == 2 ]]; then\n')
|
generated_file.write('\tif [[ $narg == 2 ]]; then\n')
|
||||||
generated_file.write('\t\topts={}\n'.format(DOMAINS_STR))
|
generated_file.write('\t\topts="{}"\n'.format(CATEGORY_STR))
|
||||||
generated_file.write('\tfi\n\n')
|
generated_file.write('\tfi\n\n')
|
||||||
|
|
||||||
# If one is currently typing an action then match with the action list
|
# If one is currently typing an action then match with the action list
|
||||||
# of the previously typed domain
|
# of the previously typed category
|
||||||
generated_file.write('\t# If one already typed a domain,\n')
|
generated_file.write('\t# If one already typed a category,\n')
|
||||||
generated_file.write('\t# match the actions of that domain\n')
|
generated_file.write('\t# match the actions or the subcategories of that category\n')
|
||||||
generated_file.write('\tif [[ $narg == 3 ]]; then\n')
|
generated_file.write('\tif [[ $narg == 3 ]]; then\n')
|
||||||
for domain in DOMAINS:
|
generated_file.write('\t\t# the category typed\n')
|
||||||
generated_file.write('\t\tif [[ $prev == "{}" ]]; then\n'.format(domain))
|
generated_file.write('\t\tcategory="${COMP_WORDS[1]}"\n\n')
|
||||||
generated_file.write('\t\t\topts={}\n'.format(ACTIONS_DICT[domain]))
|
for category in CATEGORY:
|
||||||
|
generated_file.write('\t\tif [[ $category == "{}" ]]; then\n'.format(category))
|
||||||
|
generated_file.write('\t\t\topts="{} {}"\n'.format(ACTIONS_DICT[category]["actions_str"], ACTIONS_DICT[category]["subcategories_str"]))
|
||||||
generated_file.write('\t\tfi\n')
|
generated_file.write('\t\tfi\n')
|
||||||
generated_file.write('\tfi\n\n')
|
generated_file.write('\tfi\n\n')
|
||||||
|
|
||||||
# If both domain and action have been typed or the domain
|
generated_file.write('\t# If one already typed an action or a subcategory,\n')
|
||||||
|
generated_file.write('\t# match the actions of that subcategory\n')
|
||||||
|
generated_file.write('\tif [[ $narg == 4 ]]; then\n')
|
||||||
|
generated_file.write('\t\t# the category typed\n')
|
||||||
|
generated_file.write('\t\tcategory="${COMP_WORDS[1]}"\n\n')
|
||||||
|
generated_file.write('\t\t# the action or the subcategory typed\n')
|
||||||
|
generated_file.write('\t\taction_or_subcategory="${COMP_WORDS[2]}"\n\n')
|
||||||
|
for category in CATEGORY:
|
||||||
|
if len(ACTIONS_DICT[category]["subcategories"]):
|
||||||
|
generated_file.write('\t\tif [[ $category == "{}" ]]; then\n'.format(category))
|
||||||
|
for subcategory in ACTIONS_DICT[category]["subcategories"]:
|
||||||
|
generated_file.write('\t\t\tif [[ $action_or_subcategory == "{}" ]]; then\n'.format(subcategory))
|
||||||
|
generated_file.write('\t\t\t\topts="{}"\n'.format(ACTIONS_DICT[category]["subcategories"][subcategory]["actions_str"]))
|
||||||
|
generated_file.write('\t\t\tfi\n')
|
||||||
|
generated_file.write('\t\tfi\n')
|
||||||
|
generated_file.write('\tfi\n\n')
|
||||||
|
|
||||||
|
# If both category and action have been typed or the category
|
||||||
# was not recognized propose --help (only once)
|
# was not recognized propose --help (only once)
|
||||||
generated_file.write('\t# If no options were found propose --help\n')
|
generated_file.write('\t# If no options were found propose --help\n')
|
||||||
generated_file.write('\tif [ -z "$opts" ]; then\n')
|
generated_file.write('\tif [ -z "$opts" ]; then\n')
|
||||||
|
generated_file.write('\t\tprev="${COMP_WORDS[COMP_CWORD-1]}"\n\n')
|
||||||
generated_file.write('\t\tif [[ $prev != "--help" ]]; then\n')
|
generated_file.write('\t\tif [[ $prev != "--help" ]]; then\n')
|
||||||
generated_file.write('\t\t\topts=( --help )\n')
|
generated_file.write('\t\t\topts=( --help )\n')
|
||||||
generated_file.write('\t\tfi\n')
|
generated_file.write('\t\tfi\n')
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
# [internal]
|
# [internal]
|
||||||
#
|
#
|
||||||
# usage: ynh_wait_dpkg_free
|
# usage: ynh_wait_dpkg_free
|
||||||
|
# | exit: Return 1 if dpkg is broken
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.3.1 or higher.
|
# Requires YunoHost version 3.3.1 or higher.
|
||||||
ynh_wait_dpkg_free() {
|
ynh_wait_dpkg_free() {
|
||||||
|
@ -13,7 +14,7 @@ ynh_wait_dpkg_free() {
|
||||||
for try in `seq 1 17`
|
for try in `seq 1 17`
|
||||||
do
|
do
|
||||||
# Check if /var/lib/dpkg/lock is used by another process
|
# Check if /var/lib/dpkg/lock is used by another process
|
||||||
if sudo lsof /var/lib/dpkg/lock > /dev/null
|
if lsof /var/lib/dpkg/lock > /dev/null
|
||||||
then
|
then
|
||||||
echo "apt is already in use..."
|
echo "apt is already in use..."
|
||||||
# Sleep an exponential time at each round
|
# Sleep an exponential time at each round
|
||||||
|
@ -27,7 +28,7 @@ ynh_wait_dpkg_free() {
|
||||||
while read dpkg_file <&9
|
while read dpkg_file <&9
|
||||||
do
|
do
|
||||||
# Check if the name of this file contains only numbers.
|
# Check if the name of this file contains only numbers.
|
||||||
if echo "$dpkg_file" | grep -Pq "^[[:digit:]]+$"
|
if echo "$dpkg_file" | grep --perl-regexp --quiet "^[[:digit:]]+$"
|
||||||
then
|
then
|
||||||
# If so, that a remaining of dpkg.
|
# If so, that a remaining of dpkg.
|
||||||
ynh_print_err "E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem."
|
ynh_print_err "E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem."
|
||||||
|
@ -45,20 +46,20 @@ ynh_wait_dpkg_free() {
|
||||||
# example: ynh_package_is_installed --package=yunohost && echo "ok"
|
# example: ynh_package_is_installed --package=yunohost && echo "ok"
|
||||||
#
|
#
|
||||||
# usage: ynh_package_is_installed --package=name
|
# usage: ynh_package_is_installed --package=name
|
||||||
# | arg: -p, --package - the package name to check
|
# | arg: -p, --package= - the package name to check
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_package_is_installed() {
|
ynh_package_is_installed() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=p
|
local legacy_args=p
|
||||||
declare -Ar args_array=( [p]=package= )
|
local -A args_array=( [p]=package= )
|
||||||
local package
|
local package
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
ynh_wait_dpkg_free
|
ynh_wait_dpkg_free
|
||||||
dpkg-query -W -f '${Status}' "$package" 2>/dev/null \
|
dpkg-query --show --showformat='${Status}' "$package" 2>/dev/null \
|
||||||
| grep -c "ok installed" &>/dev/null
|
| grep --count "ok installed" &>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get the version of an installed package
|
# Get the version of an installed package
|
||||||
|
@ -66,20 +67,21 @@ ynh_package_is_installed() {
|
||||||
# example: version=$(ynh_package_version --package=yunohost)
|
# example: version=$(ynh_package_version --package=yunohost)
|
||||||
#
|
#
|
||||||
# usage: ynh_package_version --package=name
|
# usage: ynh_package_version --package=name
|
||||||
# | arg: -p, --package - the package name to get version
|
# | arg: -p, --package= - the package name to get version
|
||||||
# | ret: the version or an empty string
|
# | ret: the version or an empty string
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_package_version() {
|
ynh_package_version() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=p
|
local legacy_args=p
|
||||||
declare -Ar args_array=( [p]=package= )
|
local -A args_array=( [p]=package= )
|
||||||
local package
|
local package
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
if ynh_package_is_installed "$package"; then
|
if ynh_package_is_installed "$package"
|
||||||
dpkg-query -W -f '${Version}' "$package" 2>/dev/null
|
then
|
||||||
|
dpkg-query --show --showformat='${Version}' "$package" 2>/dev/null
|
||||||
else
|
else
|
||||||
echo ''
|
echo ''
|
||||||
fi
|
fi
|
||||||
|
@ -94,7 +96,7 @@ ynh_package_version() {
|
||||||
# Requires YunoHost version 2.4.0.3 or higher.
|
# Requires YunoHost version 2.4.0.3 or higher.
|
||||||
ynh_apt() {
|
ynh_apt() {
|
||||||
ynh_wait_dpkg_free
|
ynh_wait_dpkg_free
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y $@
|
LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get --assume-yes $@
|
||||||
}
|
}
|
||||||
|
|
||||||
# Update package index files
|
# Update package index files
|
||||||
|
@ -113,8 +115,8 @@ ynh_package_update() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_package_install() {
|
ynh_package_install() {
|
||||||
ynh_apt --no-remove -o Dpkg::Options::=--force-confdef \
|
ynh_apt --no-remove --option Dpkg::Options::=--force-confdef \
|
||||||
-o Dpkg::Options::=--force-confold install $@
|
--option Dpkg::Options::=--force-confold install $@
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove package(s)
|
# Remove package(s)
|
||||||
|
@ -163,8 +165,8 @@ ynh_package_install_from_equivs () {
|
||||||
local controlfile=$1
|
local controlfile=$1
|
||||||
|
|
||||||
# retrieve package information
|
# retrieve package information
|
||||||
local pkgname=$(grep '^Package: ' $controlfile | cut -d' ' -f 2) # Retrieve the name of the debian package
|
local pkgname=$(grep '^Package: ' $controlfile | cut --delimiter=' ' --fields=2) # Retrieve the name of the debian package
|
||||||
local pkgversion=$(grep '^Version: ' $controlfile | cut -d' ' -f 2) # And its version number
|
local pkgversion=$(grep '^Version: ' $controlfile | cut --delimiter=' ' --fields=2) # And its version number
|
||||||
[[ -z "$pkgname" || -z "$pkgversion" ]] \
|
[[ -z "$pkgname" || -z "$pkgversion" ]] \
|
||||||
&& ynh_die --message="Invalid control file" # Check if this 2 variables aren't empty.
|
&& ynh_die --message="Invalid control file" # Check if this 2 variables aren't empty.
|
||||||
|
|
||||||
|
@ -172,7 +174,7 @@ ynh_package_install_from_equivs () {
|
||||||
ynh_package_update
|
ynh_package_update
|
||||||
|
|
||||||
# Build and install the package
|
# Build and install the package
|
||||||
local TMPDIR=$(mktemp -d)
|
local TMPDIR=$(mktemp --directory)
|
||||||
|
|
||||||
# Force the compatibility level at 10, levels below are deprecated
|
# Force the compatibility level at 10, levels below are deprecated
|
||||||
echo 10 > /usr/share/equivs/template/debian/compat
|
echo 10 > /usr/share/equivs/template/debian/compat
|
||||||
|
@ -184,10 +186,22 @@ ynh_package_install_from_equivs () {
|
||||||
ynh_wait_dpkg_free
|
ynh_wait_dpkg_free
|
||||||
cp "$controlfile" "${TMPDIR}/control"
|
cp "$controlfile" "${TMPDIR}/control"
|
||||||
(cd "$TMPDIR"
|
(cd "$TMPDIR"
|
||||||
equivs-build ./control 1> /dev/null
|
LC_ALL=C equivs-build ./control 1> /dev/null
|
||||||
dpkg --force-depends -i "./${pkgname}_${pkgversion}_all.deb" 2>&1)
|
dpkg --force-depends --install "./${pkgname}_${pkgversion}_all.deb" 2>&1)
|
||||||
ynh_package_install -f || ynh_die --message="Unable to install dependencies"
|
# If install fails we use "apt-get check" to try to debug and diagnose possible unmet dependencies
|
||||||
[[ -n "$TMPDIR" ]] && rm -rf $TMPDIR # Remove the temp dir.
|
# Note the use of { } which allows to group commands without starting a subshell (otherwise the ynh_die wouldn't exit the current shell).
|
||||||
|
# Be careful with the syntax : the semicolon + space at the end is important!
|
||||||
|
|
||||||
|
ynh_package_install --fix-broken || \
|
||||||
|
{ # If the installation failed
|
||||||
|
# Get the list of dependencies from the deb
|
||||||
|
local dependencies="$(dpkg --info "$TMPDIR/${pkgname}_${pkgversion}_all.deb" | grep Depends | \
|
||||||
|
sed 's/^ Depends: //' | sed 's/,//g')"
|
||||||
|
# Fake an install of those dependencies to see the errors
|
||||||
|
# The sed command here is, Print only from '--fix-broken' to the end.
|
||||||
|
ynh_package_install $dependencies --dry-run | sed --quiet '/--fix-broken/,$p' >&2
|
||||||
|
ynh_die --message="Unable to install dependencies"; }
|
||||||
|
[[ -n "$TMPDIR" ]] && rm --recursive --force $TMPDIR # Remove the temp dir.
|
||||||
|
|
||||||
# check if the package is actually installed
|
# check if the package is actually installed
|
||||||
ynh_package_is_installed "$pkgname"
|
ynh_package_is_installed "$pkgname"
|
||||||
|
@ -205,19 +219,58 @@ ynh_package_install_from_equivs () {
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_install_app_dependencies () {
|
ynh_install_app_dependencies () {
|
||||||
local dependencies=$@
|
local dependencies=$@
|
||||||
local dependencies=${dependencies// /, }
|
# Add a comma for each space between packages. But not add a comma if the space separate a version specification. (See below)
|
||||||
|
dependencies="$(echo "$dependencies" | sed 's/\([^\<=\>]\)\ \([^(]\)/\1, \2/g')"
|
||||||
local dependencies=${dependencies//|/ | }
|
local dependencies=${dependencies//|/ | }
|
||||||
local manifest_path="../manifest.json"
|
local manifest_path="../manifest.json"
|
||||||
if [ ! -e "$manifest_path" ]; then
|
if [ ! -e "$manifest_path" ]; then
|
||||||
manifest_path="../settings/manifest.json" # Into the restore script, the manifest is not at the same place
|
manifest_path="../settings/manifest.json" # Into the restore script, the manifest is not at the same place
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local version=$(grep '\"version\": ' "$manifest_path" | cut -d '"' -f 4) # Retrieve the version number in the manifest file.
|
local version=$(grep '\"version\": ' "$manifest_path" | cut --delimiter='"' --fields=4) # Retrieve the version number in the manifest file.
|
||||||
if [ ${#version} -eq 0 ]; then
|
if [ ${#version} -eq 0 ]; then
|
||||||
version="1.0"
|
version="1.0"
|
||||||
fi
|
fi
|
||||||
local dep_app=${app//_/-} # Replace all '_' by '-'
|
local dep_app=${app//_/-} # Replace all '_' by '-'
|
||||||
|
|
||||||
|
# Handle specific versions
|
||||||
|
if [[ "$dependencies" =~ [\<=\>] ]]
|
||||||
|
then
|
||||||
|
# Replace version specifications by relationships syntax
|
||||||
|
# https://www.debian.org/doc/debian-policy/ch-relationships.html
|
||||||
|
# Sed clarification
|
||||||
|
# [^(\<=\>] ignore if it begins by ( or < = >. To not apply twice.
|
||||||
|
# [\<=\>] matches < = or >
|
||||||
|
# \+ matches one or more occurence of the previous characters, for >= or >>.
|
||||||
|
# [^,]\+ matches all characters except ','
|
||||||
|
# Ex: 'package>=1.0' will be replaced by 'package (>= 1.0)'
|
||||||
|
dependencies="$(echo "$dependencies" | sed 's/\([^(\<=\>]\)\([\<=\>]\+\)\([^,]\+\)/\1 (\2 \3)/g')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Epic ugly hack to fix the goddamn dependency nightmare of sury
|
||||||
|
# Sponsored by the "Djeezusse Fokin Kraiste Why Do Adminsys Has To Be So Fucking Complicated I Should Go Grow Potatoes Instead Of This Shit" collective
|
||||||
|
# https://github.com/YunoHost/issues/issues/1407
|
||||||
|
#
|
||||||
|
# If we require to install php dependency
|
||||||
|
if echo $dependencies | grep --quiet 'php'
|
||||||
|
then
|
||||||
|
# And we have packages from sury installed (7.0.33-10+weirdshiftafter instead of 7.0.33-0 on debian)
|
||||||
|
if dpkg --list | grep "php7.0" | grep --quiet --invert-match "7.0.33-0+deb9"
|
||||||
|
then
|
||||||
|
# And sury ain't already installed
|
||||||
|
if ! grep --line-number --recursive --quiet "sury" /etc/apt/sources.list*
|
||||||
|
then
|
||||||
|
# Re-add sury
|
||||||
|
ynh_install_extra_repo --repo="https://packages.sury.org/php/ $(ynh_get_debian_release) main" --key="https://packages.sury.org/php/apt.gpg" --name=extra_php_version
|
||||||
|
|
||||||
|
# Pin this sury repository to prevent sury of doing shit
|
||||||
|
ynh_pin_repo --package="*" --pin="origin \"packages.sury.org\"" --priority=200 --name=extra_php_version
|
||||||
|
ynh_pin_repo --package="php${$YNH_DEFAULT_PHP_VERSION}*" --pin="origin \"packages.sury.org\"" --priority=600 --name=extra_php_version --append
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
cat > /tmp/${dep_app}-ynh-deps.control << EOF # Make a control file for equivs-build
|
cat > /tmp/${dep_app}-ynh-deps.control << EOF # Make a control file for equivs-build
|
||||||
Section: misc
|
Section: misc
|
||||||
Priority: optional
|
Priority: optional
|
||||||
|
@ -234,6 +287,38 @@ EOF
|
||||||
ynh_app_setting_set --app=$app --key=apt_dependencies --value="$dependencies"
|
ynh_app_setting_set --app=$app --key=apt_dependencies --value="$dependencies"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Add dependencies to install with ynh_install_app_dependencies
|
||||||
|
#
|
||||||
|
# usage: ynh_add_app_dependencies --package=phpversion [--replace]
|
||||||
|
# | arg: -p, --package= - Packages to add as dependencies for the app.
|
||||||
|
# | arg: -r, --replace - Replace dependencies instead of adding to existing ones.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_add_app_dependencies () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=pr
|
||||||
|
local -A args_array=( [p]=package= [r]=replace)
|
||||||
|
local package
|
||||||
|
local replace
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
replace=${replace:-0}
|
||||||
|
|
||||||
|
local current_dependencies=""
|
||||||
|
if [ $replace -eq 0 ]
|
||||||
|
then
|
||||||
|
local dep_app=${app//_/-} # Replace all '_' by '-'
|
||||||
|
if ynh_package_is_installed --package="${dep_app}-ynh-deps"
|
||||||
|
then
|
||||||
|
current_dependencies="$(dpkg-query --show --showformat='${Depends}' ${dep_app}-ynh-deps) "
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_dependencies=${current_dependencies// | /|}
|
||||||
|
fi
|
||||||
|
|
||||||
|
ynh_install_app_dependencies "${current_dependencies}${package}"
|
||||||
|
}
|
||||||
|
|
||||||
# Remove fake package and its dependencies
|
# Remove fake package and its dependencies
|
||||||
#
|
#
|
||||||
# Dependencies will removed only if no other package need them.
|
# Dependencies will removed only if no other package need them.
|
||||||
|
@ -245,3 +330,231 @@ ynh_remove_app_dependencies () {
|
||||||
local dep_app=${app//_/-} # Replace all '_' by '-'
|
local dep_app=${app//_/-} # Replace all '_' by '-'
|
||||||
ynh_package_autopurge ${dep_app}-ynh-deps # Remove the fake package and its dependencies if they not still used.
|
ynh_package_autopurge ${dep_app}-ynh-deps # Remove the fake package and its dependencies if they not still used.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# Install packages from an extra repository properly.
|
||||||
|
#
|
||||||
|
# usage: ynh_install_extra_app_dependencies --repo="repo" --package="dep1 dep2" [--key=key_url] [--name=name]
|
||||||
|
# | arg: -r, --repo= - Complete url of the extra repository.
|
||||||
|
# | arg: -p, --package= - The packages to install from this extra repository
|
||||||
|
# | arg: -k, --key= - url to get the public key.
|
||||||
|
# | arg: -n, --name= - Name for the files for this repo, $app as default value.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_install_extra_app_dependencies () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=rpkn
|
||||||
|
local -A args_array=( [r]=repo= [p]=package= [k]=key= [n]=name= )
|
||||||
|
local repo
|
||||||
|
local package
|
||||||
|
local key
|
||||||
|
local name
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
name="${name:-$app}"
|
||||||
|
key=${key:-}
|
||||||
|
|
||||||
|
# Set a key only if asked
|
||||||
|
if [ -n "$key" ]
|
||||||
|
then
|
||||||
|
key="--key=$key"
|
||||||
|
fi
|
||||||
|
# Add an extra repository for those packages
|
||||||
|
ynh_install_extra_repo --repo="$repo" $key --priority=995 --name=$name
|
||||||
|
|
||||||
|
# Install requested dependencies from this extra repository.
|
||||||
|
ynh_add_app_dependencies --package="$package"
|
||||||
|
|
||||||
|
# Remove this extra repository after packages are installed
|
||||||
|
ynh_remove_extra_repo --name=$app
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add an extra repository correctly, pin it and get the key.
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# usage: ynh_install_extra_repo --repo="repo" [--key=key_url] [--priority=priority_value] [--name=name] [--append]
|
||||||
|
# | arg: -r, --repo= - Complete url of the extra repository.
|
||||||
|
# | arg: -k, --key= - url to get the public key.
|
||||||
|
# | arg: -p, --priority= - Priority for the pin
|
||||||
|
# | arg: -n, --name= - Name for the files for this repo, $app as default value.
|
||||||
|
# | arg: -a, --append - Do not overwrite existing files.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_install_extra_repo () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=rkpna
|
||||||
|
local -A args_array=( [r]=repo= [k]=key= [p]=priority= [n]=name= [a]=append )
|
||||||
|
local repo
|
||||||
|
local key
|
||||||
|
local priority
|
||||||
|
local name
|
||||||
|
local append
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
name="${name:-$app}"
|
||||||
|
append=${append:-0}
|
||||||
|
key=${key:-}
|
||||||
|
priority=${priority:-}
|
||||||
|
|
||||||
|
if [ $append -eq 1 ]
|
||||||
|
then
|
||||||
|
append="--append"
|
||||||
|
wget_append="tee --append"
|
||||||
|
else
|
||||||
|
append=""
|
||||||
|
wget_append="tee"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split the repository into uri, suite and components.
|
||||||
|
# Remove "deb " at the beginning of the repo.
|
||||||
|
repo="${repo#deb }"
|
||||||
|
|
||||||
|
# Get the uri
|
||||||
|
local uri="$(echo "$repo" | awk '{ print $1 }')"
|
||||||
|
|
||||||
|
# Get the suite
|
||||||
|
local suite="$(echo "$repo" | awk '{ print $2 }')"
|
||||||
|
|
||||||
|
# Get the components
|
||||||
|
local component="${repo##$uri $suite }"
|
||||||
|
|
||||||
|
# Add the repository into sources.list.d
|
||||||
|
ynh_add_repo --uri="$uri" --suite="$suite" --component="$component" --name="$name" $append
|
||||||
|
|
||||||
|
# Pin the new repo with the default priority, so it won't be used for upgrades.
|
||||||
|
# Build $pin from the uri without http and any sub path
|
||||||
|
local pin="${uri#*://}"
|
||||||
|
pin="${pin%%/*}"
|
||||||
|
# Set a priority only if asked
|
||||||
|
if [ -n "$priority" ]
|
||||||
|
then
|
||||||
|
priority="--priority=$priority"
|
||||||
|
fi
|
||||||
|
ynh_pin_repo --package="*" --pin="origin \"$pin\"" $priority --name="$name" $append
|
||||||
|
|
||||||
|
# Get the public key for the repo
|
||||||
|
if [ -n "$key" ]
|
||||||
|
then
|
||||||
|
mkdir --parents "/etc/apt/trusted.gpg.d"
|
||||||
|
wget --quiet "$key" --output-document=- | gpg --dearmor | $wget_append /etc/apt/trusted.gpg.d/$name.gpg > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update the list of package with the new repo
|
||||||
|
ynh_package_update
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove an extra repository and the assiociated configuration.
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# usage: ynh_remove_extra_repo [--name=name]
|
||||||
|
# | arg: -n, --name= - Name for the files for this repo, $app as default value.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_remove_extra_repo () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=n
|
||||||
|
local -A args_array=( [n]=name= )
|
||||||
|
local name
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
name="${name:-$app}"
|
||||||
|
|
||||||
|
ynh_secure_remove "/etc/apt/sources.list.d/$name.list"
|
||||||
|
ynh_secure_remove "/etc/apt/preferences.d/$name"
|
||||||
|
ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.gpg"
|
||||||
|
ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.asc"
|
||||||
|
|
||||||
|
# Update the list of package to exclude the old repo
|
||||||
|
ynh_package_update
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add a repository.
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# usage: ynh_add_repo --uri=uri --suite=suite --component=component [--name=name] [--append]
|
||||||
|
# | arg: -u, --uri= - Uri of the repository.
|
||||||
|
# | arg: -s, --suite= - Suite of the repository.
|
||||||
|
# | arg: -c, --component= - Component of the repository.
|
||||||
|
# | arg: -n, --name= - Name for the files for this repo, $app as default value.
|
||||||
|
# | arg: -a, --append - Do not overwrite existing files.
|
||||||
|
#
|
||||||
|
# Example for a repo like deb http://forge.yunohost.org/debian/ stretch stable
|
||||||
|
# uri suite component
|
||||||
|
# ynh_add_repo --uri=http://forge.yunohost.org/debian/ --suite=stretch --component=stable
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_add_repo () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=uscna
|
||||||
|
local -A args_array=( [u]=uri= [s]=suite= [c]=component= [n]=name= [a]=append )
|
||||||
|
local uri
|
||||||
|
local suite
|
||||||
|
local component
|
||||||
|
local name
|
||||||
|
local append
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
name="${name:-$app}"
|
||||||
|
append=${append:-0}
|
||||||
|
|
||||||
|
if [ $append -eq 1 ]
|
||||||
|
then
|
||||||
|
append="tee --append"
|
||||||
|
else
|
||||||
|
append="tee"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir --parents "/etc/apt/sources.list.d"
|
||||||
|
# Add the new repo in sources.list.d
|
||||||
|
echo "deb $uri $suite $component" \
|
||||||
|
| $append "/etc/apt/sources.list.d/$name.list"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pin a repository.
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# usage: ynh_pin_repo --package=packages --pin=pin_filter [--priority=priority_value] [--name=name] [--append]
|
||||||
|
# | arg: -p, --package= - Packages concerned by the pin. Or all, *.
|
||||||
|
# | arg: -i, --pin= - Filter for the pin.
|
||||||
|
# | arg: -p, --priority= - Priority for the pin
|
||||||
|
# | arg: -n, --name= - Name for the files for this repo, $app as default value.
|
||||||
|
# | arg: -a, --append - Do not overwrite existing files.
|
||||||
|
#
|
||||||
|
# See https://manpages.debian.org/stretch/apt/apt_preferences.5.en.html#How_APT_Interprets_Priorities for information about pinning.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_pin_repo () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=pirna
|
||||||
|
local -A args_array=( [p]=package= [i]=pin= [r]=priority= [n]=name= [a]=append )
|
||||||
|
local package
|
||||||
|
local pin
|
||||||
|
local priority
|
||||||
|
local name
|
||||||
|
local append
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
package="${package:-*}"
|
||||||
|
priority=${priority:-50}
|
||||||
|
name="${name:-$app}"
|
||||||
|
append=${append:-0}
|
||||||
|
|
||||||
|
if [ $append -eq 1 ]
|
||||||
|
then
|
||||||
|
append="tee --append"
|
||||||
|
else
|
||||||
|
append="tee"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir --parents "/etc/apt/preferences.d"
|
||||||
|
echo "Package: $package
|
||||||
|
Pin: $pin
|
||||||
|
Pin-Priority: $priority
|
||||||
|
" \
|
||||||
|
| $append "/etc/apt/preferences.d/$name"
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,13 @@ CAN_BIND=${CAN_BIND:-1}
|
||||||
|
|
||||||
# Add a file or a directory to the list of paths to backup
|
# Add a file or a directory to the list of paths to backup
|
||||||
#
|
#
|
||||||
|
# usage: ynh_backup --src_path=src_path [--dest_path=dest_path] [--is_big] [--not_mandatory]
|
||||||
|
# | arg: -s, --src_path= - file or directory to bind or symlink or copy. it shouldn't be in the backup dir.
|
||||||
|
# | arg: -d, --dest_path= - destination file or directory inside the backup dir
|
||||||
|
# | arg: -b, --is_big - Indicate data are big (mail, video, image ...)
|
||||||
|
# | arg: -m, --not_mandatory - Indicate that if the file is missing, the backup can ignore it.
|
||||||
|
# | arg: arg - Deprecated arg
|
||||||
|
#
|
||||||
# This helper can be used both in a system backup hook, and in an app backup script
|
# This helper can be used both in a system backup hook, and in an app backup script
|
||||||
#
|
#
|
||||||
# Details: ynh_backup writes SRC and the relative DEST into a CSV file. And it
|
# Details: ynh_backup writes SRC and the relative DEST into a CSV file. And it
|
||||||
|
@ -11,13 +18,6 @@ CAN_BIND=${CAN_BIND:-1}
|
||||||
#
|
#
|
||||||
# If DEST is ended by a slash it complete this path with the basename of SRC.
|
# If DEST is ended by a slash it complete this path with the basename of SRC.
|
||||||
#
|
#
|
||||||
# usage: ynh_backup --src_path=src_path [--dest_path=dest_path] [--is_big] [--not_mandatory]
|
|
||||||
# | arg: -s, --src_path - file or directory to bind or symlink or copy. it shouldn't be in the backup dir.
|
|
||||||
# | arg: -d, --dest_path - destination file or directory inside the backup dir
|
|
||||||
# | arg: -b, --is_big - Indicate data are big (mail, video, image ...)
|
|
||||||
# | arg: -m, --not_mandatory - Indicate that if the file is missing, the backup can ignore it.
|
|
||||||
# | arg: arg - Deprecated arg
|
|
||||||
#
|
|
||||||
# Example in the context of a wordpress app
|
# Example in the context of a wordpress app
|
||||||
#
|
#
|
||||||
# ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf"
|
# ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
|
@ -41,21 +41,22 @@ CAN_BIND=${CAN_BIND:-1}
|
||||||
# # => "/etc/nginx/conf.d/$domain.d/$app.conf","apps/wordpress/conf/$app.conf"
|
# # => "/etc/nginx/conf.d/$domain.d/$app.conf","apps/wordpress/conf/$app.conf"
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.4.0 or higher.
|
# Requires YunoHost version 2.4.0 or higher.
|
||||||
|
# Requires YunoHost version 3.5.0 or higher for the argument --not_mandatory
|
||||||
ynh_backup() {
|
ynh_backup() {
|
||||||
# TODO find a way to avoid injection by file strange naming !
|
# TODO find a way to avoid injection by file strange naming !
|
||||||
|
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=sdbm
|
local legacy_args=sdbm
|
||||||
declare -Ar args_array=( [s]=src_path= [d]=dest_path= [b]=is_big [m]=not_mandatory )
|
local -A args_array=( [s]=src_path= [d]=dest_path= [b]=is_big [m]=not_mandatory )
|
||||||
local src_path
|
local src_path
|
||||||
local dest_path
|
local dest_path
|
||||||
local is_big
|
local is_big
|
||||||
local not_mandatory
|
local not_mandatory
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
local dest_path="${dest_path:-}"
|
dest_path="${dest_path:-}"
|
||||||
local is_big="${is_big:-0}"
|
is_big="${is_big:-0}"
|
||||||
local not_mandatory="${not_mandatory:-0}"
|
not_mandatory="${not_mandatory:-0}"
|
||||||
|
|
||||||
BACKUP_CORE_ONLY=${BACKUP_CORE_ONLY:-0}
|
BACKUP_CORE_ONLY=${BACKUP_CORE_ONLY:-0}
|
||||||
test -n "${app:-}" && do_not_backup_data=$(ynh_app_setting_get --app=$app --key=do_not_backup_data)
|
test -n "${app:-}" && do_not_backup_data=$(ynh_app_setting_get --app=$app --key=do_not_backup_data)
|
||||||
|
@ -64,7 +65,8 @@ ynh_backup() {
|
||||||
# don't backup big data items
|
# don't backup big data items
|
||||||
if [ $is_big -eq 1 ] && ( [ ${do_not_backup_data:-0} -eq 1 ] || [ $BACKUP_CORE_ONLY -eq 1 ] )
|
if [ $is_big -eq 1 ] && ( [ ${do_not_backup_data:-0} -eq 1 ] || [ $BACKUP_CORE_ONLY -eq 1 ] )
|
||||||
then
|
then
|
||||||
if [ $BACKUP_CORE_ONLY -eq 1 ]; then
|
if [ $BACKUP_CORE_ONLY -eq 1 ]
|
||||||
|
then
|
||||||
ynh_print_warn --message="$src_path will not be saved, because 'BACKUP_CORE_ONLY' is set."
|
ynh_print_warn --message="$src_path will not be saved, because 'BACKUP_CORE_ONLY' is set."
|
||||||
else
|
else
|
||||||
ynh_print_warn --message="$src_path will not be saved, because 'do_not_backup_data' is set."
|
ynh_print_warn --message="$src_path will not be saved, because 'do_not_backup_data' is set."
|
||||||
|
@ -76,22 +78,23 @@ ynh_backup() {
|
||||||
# Format correctly source and destination paths
|
# Format correctly source and destination paths
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Be sure the source path is not empty
|
# Be sure the source path is not empty
|
||||||
[[ -e "${src_path}" ]] || {
|
if [ ! -e "$src_path" ]
|
||||||
|
then
|
||||||
ynh_print_warn --message="Source path '${src_path}' does not exist"
|
ynh_print_warn --message="Source path '${src_path}' does not exist"
|
||||||
if [ "$not_mandatory" == "0" ]
|
if [ "$not_mandatory" == "0" ]
|
||||||
then
|
then
|
||||||
# This is a temporary fix for fail2ban config files missing after the migration to stretch.
|
# This is a temporary fix for fail2ban config files missing after the migration to stretch.
|
||||||
if echo "${src_path}" | grep --quiet "/etc/fail2ban"
|
if echo "${src_path}" | grep --quiet "/etc/fail2ban"
|
||||||
then
|
then
|
||||||
touch "${src_path}"
|
touch "${src_path}"
|
||||||
ynh_print_info --message="The missing file will be replaced by a dummy one for the backup !!!"
|
ynh_print_info --message="The missing file will be replaced by a dummy one for the backup !!!"
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
}
|
fi
|
||||||
|
|
||||||
# Transform the source path as an absolute path
|
# Transform the source path as an absolute path
|
||||||
# If it's a dir remove the ending /
|
# If it's a dir remove the ending /
|
||||||
|
@ -100,12 +103,13 @@ ynh_backup() {
|
||||||
# If there is no destination path, initialize it with the source path
|
# If there is no destination path, initialize it with the source path
|
||||||
# relative to "/".
|
# relative to "/".
|
||||||
# eg: src_path=/etc/yunohost -> dest_path=etc/yunohost
|
# eg: src_path=/etc/yunohost -> dest_path=etc/yunohost
|
||||||
if [[ -z "$dest_path" ]]; then
|
if [[ -z "$dest_path" ]]
|
||||||
|
then
|
||||||
dest_path="${src_path#/}"
|
dest_path="${src_path#/}"
|
||||||
|
|
||||||
else
|
else
|
||||||
if [[ "${dest_path:0:1}" == "/" ]]; then
|
if [[ "${dest_path:0:1}" == "/" ]]
|
||||||
|
then
|
||||||
|
|
||||||
# If the destination path is an absolute path, transform it as a path
|
# If the destination path is an absolute path, transform it as a path
|
||||||
# relative to the current working directory ($YNH_CWD)
|
# relative to the current working directory ($YNH_CWD)
|
||||||
|
@ -117,20 +121,23 @@ ynh_backup() {
|
||||||
dest_path="${dest_path#$YNH_CWD/}"
|
dest_path="${dest_path#$YNH_CWD/}"
|
||||||
|
|
||||||
# Case where $2 is an absolute dir but doesn't begin with $YNH_CWD
|
# Case where $2 is an absolute dir but doesn't begin with $YNH_CWD
|
||||||
[[ "${dest_path:0:1}" == "/" ]] \
|
if [[ "${dest_path:0:1}" == "/" ]]; then
|
||||||
&& dest_path="${dest_path#/}"
|
dest_path="${dest_path#/}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Complete dest_path if ended by a /
|
# Complete dest_path if ended by a /
|
||||||
[[ "${dest_path: -1}" == "/" ]] \
|
if [[ "${dest_path: -1}" == "/" ]]; then
|
||||||
&& dest_path="${dest_path}/$(basename $src_path)"
|
dest_path="${dest_path}/$(basename $src_path)"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if dest_path already exists in tmp archive
|
# Check if dest_path already exists in tmp archive
|
||||||
[[ ! -e "${dest_path}" ]] || {
|
if [[ -e "${dest_path}" ]]
|
||||||
|
then
|
||||||
ynh_print_err --message="Destination path '${dest_path}' already exist"
|
ynh_print_err --message="Destination path '${dest_path}' already exist"
|
||||||
return 1
|
return 1
|
||||||
}
|
fi
|
||||||
|
|
||||||
# Add the relative current working directory to the destination path
|
# Add the relative current working directory to the destination path
|
||||||
local rel_dir="${YNH_CWD#$YNH_BACKUP_DIR}"
|
local rel_dir="${YNH_CWD#$YNH_BACKUP_DIR}"
|
||||||
|
@ -142,15 +149,15 @@ ynh_backup() {
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Write file to backup into backup_list
|
# Write file to backup into backup_list
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
local src=$(echo "${src_path}" | sed -r 's/"/\"\"/g')
|
local src=$(echo "${src_path}" | sed --regexp-extended 's/"/\"\"/g')
|
||||||
local dest=$(echo "${dest_path}" | sed -r 's/"/\"\"/g')
|
local dest=$(echo "${dest_path}" | sed --regexp-extended 's/"/\"\"/g')
|
||||||
echo "\"${src}\",\"${dest}\"" >> "${YNH_BACKUP_CSV}"
|
echo "\"${src}\",\"${dest}\"" >> "${YNH_BACKUP_CSV}"
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# Create the parent dir of the destination path
|
# Create the parent dir of the destination path
|
||||||
# It's for retro compatibility, some script consider ynh_backup creates this dir
|
# It's for retro compatibility, some script consider ynh_backup creates this dir
|
||||||
mkdir -p $(dirname "$YNH_BACKUP_DIR/${dest_path}")
|
mkdir --parents $(dirname "$YNH_BACKUP_DIR/${dest_path}")
|
||||||
}
|
}
|
||||||
|
|
||||||
# Restore all files that were previously backuped in a core backup script or app backup script
|
# Restore all files that were previously backuped in a core backup script or app backup script
|
||||||
|
@ -164,10 +171,11 @@ ynh_restore () {
|
||||||
REL_DIR="${REL_DIR%/}/"
|
REL_DIR="${REL_DIR%/}/"
|
||||||
|
|
||||||
# For each destination path begining by $REL_DIR
|
# For each destination path begining by $REL_DIR
|
||||||
cat ${YNH_BACKUP_CSV} | tr -d $'\r' | grep -ohP "^\".*\",\"$REL_DIR.*\"$" | \
|
cat ${YNH_BACKUP_CSV} | tr --delete $'\r' | grep --only-matching --no-filename --perl-regexp "^\".*\",\"$REL_DIR.*\"$" | \
|
||||||
while read line; do
|
while read line
|
||||||
local ORIGIN_PATH=$(echo "$line" | grep -ohP "^\"\K.*(?=\",\".*\"$)")
|
do
|
||||||
local ARCHIVE_PATH=$(echo "$line" | grep -ohP "^\".*\",\"$REL_DIR\K.*(?=\"$)")
|
local ORIGIN_PATH=$(echo "$line" | grep --only-matching --no-filename --perl-regexp "^\"\K.*(?=\",\".*\"$)")
|
||||||
|
local ARCHIVE_PATH=$(echo "$line" | grep --only-matching --no-filename --perl-regexp "^\".*\",\"$REL_DIR\K.*(?=\"$)")
|
||||||
ynh_restore_file --origin_path="$ARCHIVE_PATH" --dest_path="$ORIGIN_PATH"
|
ynh_restore_file --origin_path="$ARCHIVE_PATH" --dest_path="$ORIGIN_PATH"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
@ -179,7 +187,7 @@ ynh_restore () {
|
||||||
# usage: _get_archive_path ORIGIN_PATH
|
# usage: _get_archive_path ORIGIN_PATH
|
||||||
_get_archive_path () {
|
_get_archive_path () {
|
||||||
# For security reasons we use csv python library to read the CSV
|
# For security reasons we use csv python library to read the CSV
|
||||||
sudo python -c "
|
python -c "
|
||||||
import sys
|
import sys
|
||||||
import csv
|
import csv
|
||||||
with open(sys.argv[1], 'r') as backup_file:
|
with open(sys.argv[1], 'r') as backup_file:
|
||||||
|
@ -199,9 +207,9 @@ with open(sys.argv[1], 'r') as backup_file:
|
||||||
# the right place.
|
# the right place.
|
||||||
#
|
#
|
||||||
# usage: ynh_restore_file --origin_path=origin_path [--dest_path=dest_path] [--not_mandatory]
|
# usage: ynh_restore_file --origin_path=origin_path [--dest_path=dest_path] [--not_mandatory]
|
||||||
# | arg: -o, --origin_path - Path where was located the file or the directory before to be backuped or relative path to $YNH_CWD where it is located in the backup archive
|
# | arg: -o, --origin_path= - Path where was located the file or the directory before to be backuped or relative path to $YNH_CWD where it is located in the backup archive
|
||||||
# | arg: -d, --dest_path - Path where restore the file or the dir, if unspecified, the destination will be ORIGIN_PATH or if the ORIGIN_PATH doesn't exist in the archive, the destination will be searched into backup.csv
|
# | arg: -d, --dest_path= - Path where restore the file or the dir, if unspecified, the destination will be ORIGIN_PATH or if the ORIGIN_PATH doesn't exist in the archive, the destination will be searched into backup.csv
|
||||||
# | arg: -m, --not_mandatory - Indicate that if the file is missing, the restore process can ignore it.
|
# | arg: -m, --not_mandatory - Indicate that if the file is missing, the restore process can ignore it.
|
||||||
#
|
#
|
||||||
# examples:
|
# examples:
|
||||||
# ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf"
|
# ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
|
@ -217,24 +225,25 @@ with open(sys.argv[1], 'r') as backup_file:
|
||||||
# /etc/nginx/conf.d/$domain.d/$app.conf
|
# /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
# Requires YunoHost version 3.5.0 or higher for the argument --not_mandatory
|
||||||
ynh_restore_file () {
|
ynh_restore_file () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=odm
|
local legacy_args=odm
|
||||||
declare -Ar args_array=( [o]=origin_path= [d]=dest_path= [m]=not_mandatory )
|
local -A args_array=( [o]=origin_path= [d]=dest_path= [m]=not_mandatory )
|
||||||
local origin_path
|
local origin_path
|
||||||
local archive_path
|
|
||||||
local dest_path
|
local dest_path
|
||||||
local not_mandatory
|
local not_mandatory
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
local origin_path="/${origin_path#/}"
|
origin_path="/${origin_path#/}"
|
||||||
local archive_path="$YNH_CWD${origin_path}"
|
|
||||||
# Default value for dest_path = /$origin_path
|
# Default value for dest_path = /$origin_path
|
||||||
local dest_path="${dest_path:-$origin_path}"
|
dest_path="${dest_path:-$origin_path}"
|
||||||
local not_mandatory="${not_mandatory:-0}"
|
not_mandatory="${not_mandatory:-0}"
|
||||||
|
|
||||||
|
local archive_path="$YNH_CWD${origin_path}"
|
||||||
# If archive_path doesn't exist, search for a corresponding path in CSV
|
# If archive_path doesn't exist, search for a corresponding path in CSV
|
||||||
if [ ! -d "$archive_path" ] && [ ! -f "$archive_path" ] && [ ! -L "$archive_path" ]; then
|
if [ ! -d "$archive_path" ] && [ ! -f "$archive_path" ] && [ ! -L "$archive_path" ]
|
||||||
|
then
|
||||||
if [ "$not_mandatory" == "0" ]
|
if [ "$not_mandatory" == "0" ]
|
||||||
then
|
then
|
||||||
archive_path="$YNH_BACKUP_DIR/$(_get_archive_path \"$origin_path\")"
|
archive_path="$YNH_BACKUP_DIR/$(_get_archive_path \"$origin_path\")"
|
||||||
|
@ -247,10 +256,10 @@ ynh_restore_file () {
|
||||||
if [[ -e "${dest_path}" ]]
|
if [[ -e "${dest_path}" ]]
|
||||||
then
|
then
|
||||||
# Check if the file/dir size is less than 500 Mo
|
# Check if the file/dir size is less than 500 Mo
|
||||||
if [[ $(du -sb ${dest_path} | cut -d"/" -f1) -le "500000000" ]]
|
if [[ $(du --summarize --bytes ${dest_path} | cut --delimiter="/" --fields=1) -le "500000000" ]]
|
||||||
then
|
then
|
||||||
local backup_file="/home/yunohost.conf/backup/${dest_path}.backup.$(date '+%Y%m%d.%H%M%S')"
|
local backup_file="/home/yunohost.conf/backup/${dest_path}.backup.$(date '+%Y%m%d.%H%M%S')"
|
||||||
mkdir -p "$(dirname "$backup_file")"
|
mkdir --parents "$(dirname "$backup_file")"
|
||||||
mv "${dest_path}" "$backup_file" # Move the current file or directory
|
mv "${dest_path}" "$backup_file" # Move the current file or directory
|
||||||
else
|
else
|
||||||
ynh_secure_remove --file=${dest_path}
|
ynh_secure_remove --file=${dest_path}
|
||||||
|
@ -258,15 +267,17 @@ ynh_restore_file () {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Restore origin_path into dest_path
|
# Restore origin_path into dest_path
|
||||||
mkdir -p $(dirname "$dest_path")
|
mkdir --parents $(dirname "$dest_path")
|
||||||
|
|
||||||
# Do a copy if it's just a mounting point
|
# Do a copy if it's just a mounting point
|
||||||
if mountpoint -q $YNH_BACKUP_DIR; then
|
if mountpoint --quiet $YNH_BACKUP_DIR
|
||||||
if [[ -d "${archive_path}" ]]; then
|
then
|
||||||
|
if [[ -d "${archive_path}" ]]
|
||||||
|
then
|
||||||
archive_path="${archive_path}/."
|
archive_path="${archive_path}/."
|
||||||
mkdir -p "$dest_path"
|
mkdir --parents "$dest_path"
|
||||||
fi
|
fi
|
||||||
cp -a "$archive_path" "${dest_path}"
|
cp --archive "$archive_path" "${dest_path}"
|
||||||
# Do a move if YNH_BACKUP_DIR is already a copy
|
# Do a move if YNH_BACKUP_DIR is already a copy
|
||||||
else
|
else
|
||||||
mv "$archive_path" "${dest_path}"
|
mv "$archive_path" "${dest_path}"
|
||||||
|
@ -287,22 +298,22 @@ ynh_bind_or_cp() {
|
||||||
|
|
||||||
# Calculate and store a file checksum into the app settings
|
# Calculate and store a file checksum into the app settings
|
||||||
#
|
#
|
||||||
# $app should be defined when calling this helper
|
|
||||||
#
|
|
||||||
# usage: ynh_store_file_checksum --file=file
|
# usage: ynh_store_file_checksum --file=file
|
||||||
# | arg: -f, --file - The file on which the checksum will performed, then stored.
|
# | arg: -f, --file= - The file on which the checksum will performed, then stored.
|
||||||
|
#
|
||||||
|
# $app should be defined when calling this helper
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_store_file_checksum () {
|
ynh_store_file_checksum () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=f
|
local legacy_args=f
|
||||||
declare -Ar args_array=( [f]=file= )
|
local -A args_array=( [f]=file= )
|
||||||
local file
|
local file
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
||||||
ynh_app_setting_set --app=$app --key=$checksum_setting_name --value=$(sudo md5sum "$file" | cut -d' ' -f1)
|
ynh_app_setting_set --app=$app --key=$checksum_setting_name --value=$(md5sum "$file" | cut --delimiter=' ' --fields=1)
|
||||||
|
|
||||||
# If backup_file_checksum isn't empty, ynh_backup_if_checksum_is_different has made a backup
|
# If backup_file_checksum isn't empty, ynh_backup_if_checksum_is_different has made a backup
|
||||||
if [ -n "${backup_file_checksum-}" ]
|
if [ -n "${backup_file_checksum-}" ]
|
||||||
|
@ -321,14 +332,14 @@ ynh_store_file_checksum () {
|
||||||
# modified config files.
|
# modified config files.
|
||||||
#
|
#
|
||||||
# usage: ynh_backup_if_checksum_is_different --file=file
|
# usage: ynh_backup_if_checksum_is_different --file=file
|
||||||
# | arg: -f, --file - The file on which the checksum test will be perfomed.
|
# | arg: -f, --file= - The file on which the checksum test will be perfomed.
|
||||||
# | ret: the name of a backup file, or nothing
|
# | ret: the name of a backup file, or nothing
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_backup_if_checksum_is_different () {
|
ynh_backup_if_checksum_is_different () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=f
|
local legacy_args=f
|
||||||
declare -Ar args_array=( [f]=file= )
|
local -A args_array=( [f]=file= )
|
||||||
local file
|
local file
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
@ -339,11 +350,11 @@ ynh_backup_if_checksum_is_different () {
|
||||||
backup_file_checksum=""
|
backup_file_checksum=""
|
||||||
if [ -n "$checksum_value" ]
|
if [ -n "$checksum_value" ]
|
||||||
then # Proceed only if a value was stored into the app settings
|
then # Proceed only if a value was stored into the app settings
|
||||||
if [ -e $file ] && ! echo "$checksum_value $file" | sudo md5sum -c --status
|
if [ -e $file ] && ! echo "$checksum_value $file" | md5sum --check --status
|
||||||
then # If the checksum is now different
|
then # If the checksum is now different
|
||||||
backup_file_checksum="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')"
|
backup_file_checksum="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')"
|
||||||
sudo mkdir -p "$(dirname "$backup_file_checksum")"
|
mkdir --parents "$(dirname "$backup_file_checksum")"
|
||||||
sudo cp -a "$file" "$backup_file_checksum" # Backup the current file
|
cp --archive "$file" "$backup_file_checksum" # Backup the current file
|
||||||
ynh_print_warn "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file_checksum"
|
ynh_print_warn "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file_checksum"
|
||||||
echo "$backup_file_checksum" # Return the name of the backup file
|
echo "$backup_file_checksum" # Return the name of the backup file
|
||||||
fi
|
fi
|
||||||
|
@ -352,16 +363,16 @@ ynh_backup_if_checksum_is_different () {
|
||||||
|
|
||||||
# Delete a file checksum from the app settings
|
# Delete a file checksum from the app settings
|
||||||
#
|
#
|
||||||
# $app should be defined when calling this helper
|
# usage: ynh_delete_file_checksum --file=file
|
||||||
|
# | arg: -f, --file= - The file for which the checksum will be deleted
|
||||||
#
|
#
|
||||||
# usage: ynh_remove_file_checksum file
|
# $app should be defined when calling this helper
|
||||||
# | arg: -f, --file= - The file for which the checksum will be deleted
|
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.3.1 or higher.
|
# Requires YunoHost version 3.3.1 or higher.
|
||||||
ynh_delete_file_checksum () {
|
ynh_delete_file_checksum () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=f
|
local legacy_args=f
|
||||||
declare -Ar args_array=( [f]=file= )
|
local -A args_array=( [f]=file= )
|
||||||
local file
|
local file
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
@ -373,11 +384,11 @@ ynh_delete_file_checksum () {
|
||||||
# Make a backup in case of failed upgrade
|
# Make a backup in case of failed upgrade
|
||||||
#
|
#
|
||||||
# usage:
|
# usage:
|
||||||
# ynh_backup_before_upgrade
|
# ynh_backup_before_upgrade
|
||||||
# ynh_clean_setup () {
|
# ynh_clean_setup () {
|
||||||
# ynh_restore_upgradebackup
|
# ynh_restore_upgradebackup
|
||||||
# }
|
# }
|
||||||
# ynh_abort_if_errors
|
# ynh_abort_if_errors
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
ynh_backup_before_upgrade () {
|
ynh_backup_before_upgrade () {
|
||||||
|
@ -394,7 +405,7 @@ ynh_backup_before_upgrade () {
|
||||||
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
||||||
then
|
then
|
||||||
# Check if a backup already exists with the prefix 1
|
# Check if a backup already exists with the prefix 1
|
||||||
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade1
|
if yunohost backup list | grep --quiet $app_bck-pre-upgrade1
|
||||||
then
|
then
|
||||||
# Prefix becomes 2 to preserve the previous backup
|
# Prefix becomes 2 to preserve the previous backup
|
||||||
backup_number=2
|
backup_number=2
|
||||||
|
@ -402,14 +413,14 @@ ynh_backup_before_upgrade () {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create backup
|
# Create backup
|
||||||
sudo BACKUP_CORE_ONLY=1 yunohost backup create --apps $app --name $app_bck-pre-upgrade$backup_number --debug
|
BACKUP_CORE_ONLY=1 yunohost backup create --apps $app --name $app_bck-pre-upgrade$backup_number --debug
|
||||||
if [ "$?" -eq 0 ]
|
if [ "$?" -eq 0 ]
|
||||||
then
|
then
|
||||||
# If the backup succeeded, remove the previous backup
|
# If the backup succeeded, remove the previous backup
|
||||||
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$old_backup_number
|
if yunohost backup list | grep --quiet $app_bck-pre-upgrade$old_backup_number
|
||||||
then
|
then
|
||||||
# Remove the previous backup only if it exists
|
# Remove the previous backup only if it exists
|
||||||
sudo yunohost backup delete $app_bck-pre-upgrade$old_backup_number > /dev/null
|
yunohost backup delete $app_bck-pre-upgrade$old_backup_number > /dev/null
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
ynh_die --message="Backup failed, the upgrade process was aborted."
|
ynh_die --message="Backup failed, the upgrade process was aborted."
|
||||||
|
@ -422,11 +433,11 @@ ynh_backup_before_upgrade () {
|
||||||
# Restore a previous backup if the upgrade process failed
|
# Restore a previous backup if the upgrade process failed
|
||||||
#
|
#
|
||||||
# usage:
|
# usage:
|
||||||
# ynh_backup_before_upgrade
|
# ynh_backup_before_upgrade
|
||||||
# ynh_clean_setup () {
|
# ynh_clean_setup () {
|
||||||
# ynh_restore_upgradebackup
|
# ynh_restore_upgradebackup
|
||||||
# }
|
# }
|
||||||
# ynh_abort_if_errors
|
# ynh_abort_if_errors
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
ynh_restore_upgradebackup () {
|
ynh_restore_upgradebackup () {
|
||||||
|
@ -438,12 +449,12 @@ ynh_restore_upgradebackup () {
|
||||||
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
||||||
then
|
then
|
||||||
# Check if an existing backup can be found before removing and restoring the application.
|
# Check if an existing backup can be found before removing and restoring the application.
|
||||||
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$backup_number
|
if yunohost backup list | grep --quiet $app_bck-pre-upgrade$backup_number
|
||||||
then
|
then
|
||||||
# Remove the application then restore it
|
# Remove the application then restore it
|
||||||
sudo yunohost app remove $app
|
yunohost app remove $app
|
||||||
# Restore the backup
|
# Restore the backup
|
||||||
sudo yunohost backup restore $app_bck-pre-upgrade$backup_number --apps $app --force --debug
|
yunohost backup restore $app_bck-pre-upgrade$backup_number --apps $app --force --debug
|
||||||
ynh_die --message="The app was restored to the way it was before the failed upgrade."
|
ynh_die --message="The app was restored to the way it was before the failed upgrade."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
|
|
@ -63,52 +63,54 @@
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_add_fail2ban_config () {
|
ynh_add_fail2ban_config () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=lrmptv
|
local legacy_args=lrmptv
|
||||||
declare -Ar args_array=( [l]=logpath= [r]=failregex= [m]=max_retry= [p]=ports= [t]=use_template [v]=others_var=)
|
local -A args_array=( [l]=logpath= [r]=failregex= [m]=max_retry= [p]=ports= [t]=use_template [v]=others_var=)
|
||||||
local logpath
|
local logpath
|
||||||
local failregex
|
local failregex
|
||||||
local max_retry
|
local max_retry
|
||||||
local ports
|
local ports
|
||||||
local others_var
|
local others_var
|
||||||
local use_template
|
local use_template
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
use_template="${use_template:-0}"
|
max_retry=${max_retry:-3}
|
||||||
max_retry=${max_retry:-3}
|
ports=${ports:-http,https}
|
||||||
ports=${ports:-http,https}
|
others_var=${others_var:-}
|
||||||
|
use_template="${use_template:-0}"
|
||||||
|
|
||||||
finalfail2banjailconf="/etc/fail2ban/jail.d/$app.conf"
|
finalfail2banjailconf="/etc/fail2ban/jail.d/$app.conf"
|
||||||
finalfail2banfilterconf="/etc/fail2ban/filter.d/$app.conf"
|
finalfail2banfilterconf="/etc/fail2ban/filter.d/$app.conf"
|
||||||
ynh_backup_if_checksum_is_different "$finalfail2banjailconf"
|
ynh_backup_if_checksum_is_different "$finalfail2banjailconf"
|
||||||
ynh_backup_if_checksum_is_different "$finalfail2banfilterconf"
|
ynh_backup_if_checksum_is_different "$finalfail2banfilterconf"
|
||||||
|
|
||||||
if [ $use_template -eq 1 ]
|
if [ $use_template -eq 1 ]
|
||||||
then
|
|
||||||
# Usage 2, templates
|
|
||||||
cp ../conf/f2b_jail.conf $finalfail2banjailconf
|
|
||||||
cp ../conf/f2b_filter.conf $finalfail2banfilterconf
|
|
||||||
|
|
||||||
if [ -n "${app:-}" ]
|
|
||||||
then
|
then
|
||||||
ynh_replace_string "__APP__" "$app" "$finalfail2banjailconf"
|
# Usage 2, templates
|
||||||
ynh_replace_string "__APP__" "$app" "$finalfail2banfilterconf"
|
cp ../conf/f2b_jail.conf $finalfail2banjailconf
|
||||||
fi
|
cp ../conf/f2b_filter.conf $finalfail2banfilterconf
|
||||||
|
|
||||||
# Replace all other variable given as arguments
|
if [ -n "${app:-}" ]
|
||||||
for var_to_replace in ${others_var:-}; do
|
then
|
||||||
# ${var_to_replace^^} make the content of the variable on upper-cases
|
ynh_replace_string "__APP__" "$app" "$finalfail2banjailconf"
|
||||||
# ${!var_to_replace} get the content of the variable named $var_to_replace
|
ynh_replace_string "__APP__" "$app" "$finalfail2banfilterconf"
|
||||||
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalfail2banjailconf"
|
fi
|
||||||
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalfail2banfilterconf"
|
|
||||||
done
|
|
||||||
|
|
||||||
else
|
# Replace all other variable given as arguments
|
||||||
# Usage 1, no template. Build a config file from scratch.
|
for var_to_replace in $others_var
|
||||||
test -n "$logpath" || ynh_die "ynh_add_fail2ban_config expects a logfile path as first argument and received nothing."
|
do
|
||||||
test -n "$failregex" || ynh_die "ynh_add_fail2ban_config expects a failure regex as second argument and received nothing."
|
# ${var_to_replace^^} make the content of the variable on upper-cases
|
||||||
|
# ${!var_to_replace} get the content of the variable named $var_to_replace
|
||||||
|
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalfail2banjailconf"
|
||||||
|
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalfail2banfilterconf"
|
||||||
|
done
|
||||||
|
|
||||||
tee $finalfail2banjailconf <<EOF
|
else
|
||||||
|
# Usage 1, no template. Build a config file from scratch.
|
||||||
|
test -n "$logpath" || ynh_die "ynh_add_fail2ban_config expects a logfile path as first argument and received nothing."
|
||||||
|
test -n "$failregex" || ynh_die "ynh_add_fail2ban_config expects a failure regex as second argument and received nothing."
|
||||||
|
|
||||||
|
tee $finalfail2banjailconf <<EOF
|
||||||
[$app]
|
[$app]
|
||||||
enabled = true
|
enabled = true
|
||||||
port = $ports
|
port = $ports
|
||||||
|
@ -124,19 +126,20 @@ before = common.conf
|
||||||
failregex = $failregex
|
failregex = $failregex
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Common to usage 1 and 2.
|
# Common to usage 1 and 2.
|
||||||
ynh_store_file_checksum "$finalfail2banjailconf"
|
ynh_store_file_checksum "$finalfail2banjailconf"
|
||||||
ynh_store_file_checksum "$finalfail2banfilterconf"
|
ynh_store_file_checksum "$finalfail2banfilterconf"
|
||||||
|
|
||||||
ynh_systemd_action --service_name=fail2ban --action=reload
|
ynh_systemd_action --service_name=fail2ban --action=reload --line_match="(Started|Reloaded) Fail2Ban Service" --log_path=systemd
|
||||||
|
|
||||||
local fail2ban_error="$(journalctl -u fail2ban | tail -n50 | grep "WARNING.*$app.*")"
|
local fail2ban_error="$(journalctl --unit=fail2ban | tail --lines=50 | grep "WARNING.*$app.*")"
|
||||||
if [[ -n "$fail2ban_error" ]]; then
|
if [[ -n "$fail2ban_error" ]]
|
||||||
ynh_print_err --message="Fail2ban failed to load the jail for $app"
|
then
|
||||||
ynh_print_warn --message="${fail2ban_error#*WARNING}"
|
ynh_print_err --message="Fail2ban failed to load the jail for $app"
|
||||||
fi
|
ynh_print_warn --message="${fail2ban_error#*WARNING}"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove the dedicated fail2ban config (jail and filter conf files)
|
# Remove the dedicated fail2ban config (jail and filter conf files)
|
||||||
|
@ -145,7 +148,7 @@ EOF
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_remove_fail2ban_config () {
|
ynh_remove_fail2ban_config () {
|
||||||
ynh_secure_remove "/etc/fail2ban/jail.d/$app.conf"
|
ynh_secure_remove "/etc/fail2ban/jail.d/$app.conf"
|
||||||
ynh_secure_remove "/etc/fail2ban/filter.d/$app.conf"
|
ynh_secure_remove "/etc/fail2ban/filter.d/$app.conf"
|
||||||
ynh_systemd_action --service_name=fail2ban --action=reload
|
ynh_systemd_action --service_name=fail2ban --action=reload
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
# example: function my_helper()
|
# example: function my_helper()
|
||||||
# {
|
# {
|
||||||
# declare -Ar args_array=( [a]=arg1= [b]=arg2= [c]=arg3 )
|
# local -A args_array=( [a]=arg1= [b]=arg2= [c]=arg3 )
|
||||||
# local arg1
|
# local arg1
|
||||||
# local arg2
|
# local arg2
|
||||||
# local arg3
|
# local arg3
|
||||||
|
@ -22,13 +22,13 @@
|
||||||
# This helper need an array, named "args_array" with all the arguments used by the helper
|
# This helper need an array, named "args_array" with all the arguments used by the helper
|
||||||
# that want to use ynh_handle_getopts_args
|
# that want to use ynh_handle_getopts_args
|
||||||
# Be carreful, this array has to be an associative array, as the following example:
|
# Be carreful, this array has to be an associative array, as the following example:
|
||||||
# declare -Ar args_array=( [a]=arg1 [b]=arg2= [c]=arg3 )
|
# local -A args_array=( [a]=arg1 [b]=arg2= [c]=arg3 )
|
||||||
# Let's explain this array:
|
# Let's explain this array:
|
||||||
# a, b and c are short options, -a, -b and -c
|
# a, b and c are short options, -a, -b and -c
|
||||||
# arg1, arg2 and arg3 are the long options associated to the previous short ones. --arg1, --arg2 and --arg3
|
# arg1, arg2 and arg3 are the long options associated to the previous short ones. --arg1, --arg2 and --arg3
|
||||||
# For each option, a short and long version has to be defined.
|
# For each option, a short and long version has to be defined.
|
||||||
# Let's see something more significant
|
# Let's see something more significant
|
||||||
# declare -Ar args_array=( [u]=user [f]=finalpath= [d]=database )
|
# local -A args_array=( [u]=user [f]=finalpath= [d]=database )
|
||||||
#
|
#
|
||||||
# NB: Because we're using 'declare' without -g, the array will be declared as a local variable.
|
# NB: Because we're using 'declare' without -g, the array will be declared as a local variable.
|
||||||
#
|
#
|
||||||
|
@ -46,173 +46,179 @@
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.2.2 or higher.
|
# Requires YunoHost version 3.2.2 or higher.
|
||||||
ynh_handle_getopts_args () {
|
ynh_handle_getopts_args () {
|
||||||
# Manage arguments only if there's some provided
|
# Manage arguments only if there's some provided
|
||||||
set +x
|
set +o xtrace # set +x
|
||||||
if [ $# -ne 0 ]
|
if [ $# -ne 0 ]
|
||||||
then
|
then
|
||||||
# Store arguments in an array to keep each argument separated
|
# Store arguments in an array to keep each argument separated
|
||||||
local arguments=("$@")
|
local arguments=("$@")
|
||||||
|
|
||||||
# For each option in the array, reduce to short options for getopts (e.g. for [u]=user, --user will be -u)
|
# For each option in the array, reduce to short options for getopts (e.g. for [u]=user, --user will be -u)
|
||||||
# And built parameters string for getopts
|
# And built parameters string for getopts
|
||||||
# ${!args_array[@]} is the list of all option_flags in the array (An option_flag is 'u' in [u]=user, user is a value)
|
# ${!args_array[@]} is the list of all option_flags in the array (An option_flag is 'u' in [u]=user, user is a value)
|
||||||
local getopts_parameters=""
|
local getopts_parameters=""
|
||||||
local option_flag=""
|
local option_flag=""
|
||||||
for option_flag in "${!args_array[@]}"
|
for option_flag in "${!args_array[@]}"
|
||||||
do
|
do
|
||||||
# Concatenate each option_flags of the array to build the string of arguments for getopts
|
# Concatenate each option_flags of the array to build the string of arguments for getopts
|
||||||
# Will looks like 'abcd' for -a -b -c -d
|
# Will looks like 'abcd' for -a -b -c -d
|
||||||
# If the value of an option_flag finish by =, it's an option with additionnal values. (e.g. --user bob or -u bob)
|
# If the value of an option_flag finish by =, it's an option with additionnal values. (e.g. --user bob or -u bob)
|
||||||
# Check the last character of the value associate to the option_flag
|
# Check the last character of the value associate to the option_flag
|
||||||
if [ "${args_array[$option_flag]: -1}" = "=" ]
|
if [ "${args_array[$option_flag]: -1}" = "=" ]
|
||||||
then
|
then
|
||||||
# For an option with additionnal values, add a ':' after the letter for getopts.
|
# For an option with additionnal values, add a ':' after the letter for getopts.
|
||||||
getopts_parameters="${getopts_parameters}${option_flag}:"
|
getopts_parameters="${getopts_parameters}${option_flag}:"
|
||||||
else
|
else
|
||||||
getopts_parameters="${getopts_parameters}${option_flag}"
|
getopts_parameters="${getopts_parameters}${option_flag}"
|
||||||
fi
|
fi
|
||||||
# Check each argument given to the function
|
# Check each argument given to the function
|
||||||
local arg=""
|
local arg=""
|
||||||
# ${#arguments[@]} is the size of the array
|
# ${#arguments[@]} is the size of the array
|
||||||
for arg in `seq 0 $(( ${#arguments[@]} - 1 ))`
|
for arg in `seq 0 $(( ${#arguments[@]} - 1 ))`
|
||||||
do
|
do
|
||||||
# Escape options' values starting with -. Otherwise the - will be considered as another option.
|
# Escape options' values starting with -. Otherwise the - will be considered as another option.
|
||||||
arguments[arg]="${arguments[arg]//--${args_array[$option_flag]}-/--${args_array[$option_flag]}\\TOBEREMOVED\\-}"
|
arguments[arg]="${arguments[arg]//--${args_array[$option_flag]}-/--${args_array[$option_flag]}\\TOBEREMOVED\\-}"
|
||||||
# And replace long option (value of the option_flag) by the short option, the option_flag itself
|
# And replace long option (value of the option_flag) by the short option, the option_flag itself
|
||||||
# (e.g. for [u]=user, --user will be -u)
|
# (e.g. for [u]=user, --user will be -u)
|
||||||
# Replace long option with =
|
# Replace long option with =
|
||||||
arguments[arg]="${arguments[arg]//--${args_array[$option_flag]}/-${option_flag} }"
|
arguments[arg]="${arguments[arg]//--${args_array[$option_flag]}/-${option_flag} }"
|
||||||
# And long option without =
|
# And long option without =
|
||||||
arguments[arg]="${arguments[arg]//--${args_array[$option_flag]%=}/-${option_flag}}"
|
arguments[arg]="${arguments[arg]//--${args_array[$option_flag]%=}/-${option_flag}}"
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
# Read and parse all the arguments
|
# Read and parse all the arguments
|
||||||
# Use a function here, to use standart arguments $@ and be able to use shift.
|
# Use a function here, to use standart arguments $@ and be able to use shift.
|
||||||
parse_arg () {
|
parse_arg () {
|
||||||
# Read all arguments, until no arguments are left
|
# Read all arguments, until no arguments are left
|
||||||
while [ $# -ne 0 ]
|
while [ $# -ne 0 ]
|
||||||
do
|
do
|
||||||
# Initialize the index of getopts
|
# Initialize the index of getopts
|
||||||
OPTIND=1
|
OPTIND=1
|
||||||
# Parse with getopts only if the argument begin by -, that means the argument is an option
|
# Parse with getopts only if the argument begin by -, that means the argument is an option
|
||||||
# getopts will fill $parameter with the letter of the option it has read.
|
# getopts will fill $parameter with the letter of the option it has read.
|
||||||
local parameter=""
|
local parameter=""
|
||||||
getopts ":$getopts_parameters" parameter || true
|
getopts ":$getopts_parameters" parameter || true
|
||||||
|
|
||||||
if [ "$parameter" = "?" ]
|
if [ "$parameter" = "?" ]
|
||||||
then
|
then
|
||||||
ynh_die --message="Invalid argument: -${OPTARG:-}"
|
ynh_die --message="Invalid argument: -${OPTARG:-}"
|
||||||
elif [ "$parameter" = ":" ]
|
elif [ "$parameter" = ":" ]
|
||||||
then
|
then
|
||||||
ynh_die --message="-$OPTARG parameter requires an argument."
|
ynh_die --message="-$OPTARG parameter requires an argument."
|
||||||
else
|
else
|
||||||
local shift_value=1
|
local shift_value=1
|
||||||
# Use the long option, corresponding to the short option read by getopts, as a variable
|
# Use the long option, corresponding to the short option read by getopts, as a variable
|
||||||
# (e.g. for [u]=user, 'user' will be used as a variable)
|
# (e.g. for [u]=user, 'user' will be used as a variable)
|
||||||
# Also, remove '=' at the end of the long option
|
# Also, remove '=' at the end of the long option
|
||||||
# The variable name will be stored in 'option_var'
|
# The variable name will be stored in 'option_var'
|
||||||
local option_var="${args_array[$parameter]%=}"
|
local option_var="${args_array[$parameter]%=}"
|
||||||
# If this option doesn't take values
|
# If this option doesn't take values
|
||||||
# if there's a '=' at the end of the long option name, this option takes values
|
# if there's a '=' at the end of the long option name, this option takes values
|
||||||
if [ "${args_array[$parameter]: -1}" != "=" ]
|
if [ "${args_array[$parameter]: -1}" != "=" ]
|
||||||
then
|
then
|
||||||
# 'eval ${option_var}' will use the content of 'option_var'
|
# 'eval ${option_var}' will use the content of 'option_var'
|
||||||
eval ${option_var}=1
|
eval ${option_var}=1
|
||||||
else
|
else
|
||||||
# Read all other arguments to find multiple value for this option.
|
# Read all other arguments to find multiple value for this option.
|
||||||
# Load args in a array
|
# Load args in a array
|
||||||
local all_args=("$@")
|
local all_args=("$@")
|
||||||
|
|
||||||
# If the first argument is longer than 2 characters,
|
# If the first argument is longer than 2 characters,
|
||||||
# There's a value attached to the option, in the same array cell
|
# There's a value attached to the option, in the same array cell
|
||||||
if [ ${#all_args[0]} -gt 2 ]; then
|
if [ ${#all_args[0]} -gt 2 ]
|
||||||
# Remove the option and the space, so keep only the value itself.
|
then
|
||||||
all_args[0]="${all_args[0]#-${parameter} }"
|
# Remove the option and the space, so keep only the value itself.
|
||||||
# Reduce the value of shift, because the option has been removed manually
|
all_args[0]="${all_args[0]#-${parameter} }"
|
||||||
shift_value=$(( shift_value - 1 ))
|
# Reduce the value of shift, because the option has been removed manually
|
||||||
fi
|
shift_value=$(( shift_value - 1 ))
|
||||||
|
fi
|
||||||
|
|
||||||
# Declare the content of option_var as a variable.
|
# Declare the content of option_var as a variable.
|
||||||
eval ${option_var}=""
|
eval ${option_var}=""
|
||||||
# Then read the array value per value
|
# Then read the array value per value
|
||||||
local i
|
local i
|
||||||
for i in `seq 0 $(( ${#all_args[@]} - 1 ))`
|
for i in `seq 0 $(( ${#all_args[@]} - 1 ))`
|
||||||
do
|
do
|
||||||
# If this argument is an option, end here.
|
# If this argument is an option, end here.
|
||||||
if [ "${all_args[$i]:0:1}" == "-" ]
|
if [ "${all_args[$i]:0:1}" == "-" ]
|
||||||
then
|
then
|
||||||
# Ignore the first value of the array, which is the option itself
|
# Ignore the first value of the array, which is the option itself
|
||||||
if [ "$i" -ne 0 ]; then
|
if [ "$i" -ne 0 ]; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Else, add this value to this option
|
# Ignore empty parameters
|
||||||
# Each value will be separated by ';'
|
if [ -n "${all_args[$i]}" ]
|
||||||
if [ -n "${!option_var}" ]
|
then
|
||||||
then
|
# Else, add this value to this option
|
||||||
# If there's already another value for this option, add a ; before adding the new value
|
# Each value will be separated by ';'
|
||||||
eval ${option_var}+="\;"
|
if [ -n "${!option_var}" ]
|
||||||
fi
|
then
|
||||||
|
# If there's already another value for this option, add a ; before adding the new value
|
||||||
|
eval ${option_var}+="\;"
|
||||||
|
fi
|
||||||
|
|
||||||
# Remove the \ that escape - at beginning of values.
|
# Remove the \ that escape - at beginning of values.
|
||||||
all_args[i]="${all_args[i]//\\TOBEREMOVED\\/}"
|
all_args[i]="${all_args[i]//\\TOBEREMOVED\\/}"
|
||||||
|
|
||||||
# For the record.
|
# For the record.
|
||||||
# We're using eval here to get the content of the variable stored itself as simple text in $option_var...
|
# We're using eval here to get the content of the variable stored itself as simple text in $option_var...
|
||||||
# Other ways to get that content would be to use either ${!option_var} or declare -g ${option_var}
|
# Other ways to get that content would be to use either ${!option_var} or declare -g ${option_var}
|
||||||
# But... ${!option_var} can't be used as left part of an assignation.
|
# But... ${!option_var} can't be used as left part of an assignation.
|
||||||
# declare -g ${option_var} will create a local variable (despite -g !) and will not be available for the helper itself.
|
# declare -g ${option_var} will create a local variable (despite -g !) and will not be available for the helper itself.
|
||||||
# So... Stop fucking arguing each time that eval is evil... Go find an other working solution if you can find one!
|
# So... Stop fucking arguing each time that eval is evil... Go find an other working solution if you can find one!
|
||||||
|
|
||||||
eval ${option_var}+='"${all_args[$i]}"'
|
eval ${option_var}+='"${all_args[$i]}"'
|
||||||
shift_value=$(( shift_value + 1 ))
|
fi
|
||||||
fi
|
shift_value=$(( shift_value + 1 ))
|
||||||
done
|
fi
|
||||||
fi
|
done
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Shift the parameter and its argument(s)
|
# Shift the parameter and its argument(s)
|
||||||
shift $shift_value
|
shift $shift_value
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# LEGACY MODE
|
# LEGACY MODE
|
||||||
# Check if there's getopts arguments
|
# Check if there's getopts arguments
|
||||||
if [ "${arguments[0]:0:1}" != "-" ]
|
if [ "${arguments[0]:0:1}" != "-" ]
|
||||||
then
|
then
|
||||||
# If not, enter in legacy mode and manage the arguments as positionnal ones..
|
# If not, enter in legacy mode and manage the arguments as positionnal ones..
|
||||||
# Dot not echo, to prevent to go through a helper output. But print only in the log.
|
# Dot not echo, to prevent to go through a helper output. But print only in the log.
|
||||||
set -x; echo "! Helper used in legacy mode !" > /dev/null; set +x
|
set -x; echo "! Helper used in legacy mode !" > /dev/null; set +x
|
||||||
local i
|
local i
|
||||||
for i in `seq 0 $(( ${#arguments[@]} -1 ))`
|
for i in `seq 0 $(( ${#arguments[@]} -1 ))`
|
||||||
do
|
do
|
||||||
# Try to use legacy_args as a list of option_flag of the array args_array
|
# Try to use legacy_args as a list of option_flag of the array args_array
|
||||||
# Otherwise, fallback to getopts_parameters to get the option_flag. But an associative arrays isn't always sorted in the correct order...
|
# Otherwise, fallback to getopts_parameters to get the option_flag. But an associative arrays isn't always sorted in the correct order...
|
||||||
# Remove all ':' in getopts_parameters
|
# Remove all ':' in getopts_parameters
|
||||||
getopts_parameters=${legacy_args:-${getopts_parameters//:}}
|
getopts_parameters=${legacy_args:-${getopts_parameters//:}}
|
||||||
# Get the option_flag from getopts_parameters, by using the option_flag according to the position of the argument.
|
# Get the option_flag from getopts_parameters, by using the option_flag according to the position of the argument.
|
||||||
option_flag=${getopts_parameters:$i:1}
|
option_flag=${getopts_parameters:$i:1}
|
||||||
if [ -z "$option_flag" ]; then
|
if [ -z "$option_flag" ]
|
||||||
ynh_print_warn --message="Too many arguments ! \"${arguments[$i]}\" will be ignored."
|
then
|
||||||
continue
|
ynh_print_warn --message="Too many arguments ! \"${arguments[$i]}\" will be ignored."
|
||||||
fi
|
continue
|
||||||
# Use the long option, corresponding to the option_flag, as a variable
|
fi
|
||||||
# (e.g. for [u]=user, 'user' will be used as a variable)
|
# Use the long option, corresponding to the option_flag, as a variable
|
||||||
# Also, remove '=' at the end of the long option
|
# (e.g. for [u]=user, 'user' will be used as a variable)
|
||||||
# The variable name will be stored in 'option_var'
|
# Also, remove '=' at the end of the long option
|
||||||
local option_var="${args_array[$option_flag]%=}"
|
# The variable name will be stored in 'option_var'
|
||||||
|
local option_var="${args_array[$option_flag]%=}"
|
||||||
|
|
||||||
# Store each value given as argument in the corresponding variable
|
# Store each value given as argument in the corresponding variable
|
||||||
# The values will be stored in the same order than $args_array
|
# The values will be stored in the same order than $args_array
|
||||||
eval ${option_var}+='"${arguments[$i]}"'
|
eval ${option_var}+='"${arguments[$i]}"'
|
||||||
done
|
done
|
||||||
unset legacy_args
|
unset legacy_args
|
||||||
else
|
else
|
||||||
# END LEGACY MODE
|
# END LEGACY MODE
|
||||||
# Call parse_arg and pass the modified list of args as an array of arguments.
|
# Call parse_arg and pass the modified list of args as an array of arguments.
|
||||||
parse_arg "${arguments[@]}"
|
parse_arg "${arguments[@]}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
set -x
|
set -o xtrace # set -x
|
||||||
}
|
}
|
||||||
|
|
108
data/helpers.d/hardware
Normal file
108
data/helpers.d/hardware
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Get the total or free amount of RAM+swap on the system
|
||||||
|
#
|
||||||
|
# usage: ynh_get_ram [--free|--total] [--ignore_swap|--only_swap]
|
||||||
|
# | arg: -f, --free - Count free RAM+swap
|
||||||
|
# | arg: -t, --total - Count total RAM+swap
|
||||||
|
# | arg: -s, --ignore_swap - Ignore swap, consider only real RAM
|
||||||
|
# | arg: -o, --only_swap - Ignore real RAM, consider only swap
|
||||||
|
# | ret: the amount of free ram
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_get_ram () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=ftso
|
||||||
|
local -A args_array=( [f]=free [t]=total [s]=ignore_swap [o]=only_swap )
|
||||||
|
local free
|
||||||
|
local total
|
||||||
|
local ignore_swap
|
||||||
|
local only_swap
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
ignore_swap=${ignore_swap:-0}
|
||||||
|
only_swap=${only_swap:-0}
|
||||||
|
free=${free:-0}
|
||||||
|
total=${total:-0}
|
||||||
|
|
||||||
|
local total_ram=$(vmstat --stats --unit M | grep "total memory" | awk '{print $1}')
|
||||||
|
local total_swap=$(vmstat --stats --unit M | grep "total swap" | awk '{print $1}')
|
||||||
|
local total_ram_swap=$(( total_ram + total_swap ))
|
||||||
|
|
||||||
|
local free_ram=$(vmstat --stats --unit M | grep "free memory" | awk '{print $1}')
|
||||||
|
local free_swap=$(vmstat --stats --unit M | grep "free swap" | awk '{print $1}')
|
||||||
|
local free_ram_swap=$(( free_ram + free_swap ))
|
||||||
|
|
||||||
|
# Use the total amount of ram
|
||||||
|
if [ $free -eq 1 ]
|
||||||
|
then
|
||||||
|
# Use the total amount of free ram
|
||||||
|
local ram=$free_ram_swap
|
||||||
|
if [ $ignore_swap -eq 1 ]
|
||||||
|
then
|
||||||
|
# Use only the amount of free ram
|
||||||
|
ram=$free_ram
|
||||||
|
elif [ $only_swap -eq 1 ]
|
||||||
|
then
|
||||||
|
# Use only the amount of free swap
|
||||||
|
ram=$free_swap
|
||||||
|
fi
|
||||||
|
elif [ $total -eq 1 ]
|
||||||
|
then
|
||||||
|
local ram=$total_ram_swap
|
||||||
|
if [ $ignore_swap -eq 1 ]
|
||||||
|
then
|
||||||
|
# Use only the amount of free ram
|
||||||
|
ram=$total_ram
|
||||||
|
elif [ $only_swap -eq 1 ]
|
||||||
|
then
|
||||||
|
# Use only the amount of free swap
|
||||||
|
ram=$total_swap
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
ynh_print_warn --message="You have to choose --free or --total when using ynh_get_ram"
|
||||||
|
ram=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $ram
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return 0 or 1 depending if the system has a given amount of RAM+swap free or total
|
||||||
|
#
|
||||||
|
# usage: ynh_require_ram --required=RAM required in Mb [--free|--total] [--ignore_swap|--only_swap]
|
||||||
|
# | arg: -r, --required= - The amount to require, in Mb
|
||||||
|
# | arg: -f, --free - Count free RAM+swap
|
||||||
|
# | arg: -t, --total - Count total RAM+swap
|
||||||
|
# | arg: -s, --ignore_swap - Ignore swap, consider only real RAM
|
||||||
|
# | arg: -o, --only_swap - Ignore real RAM, consider only swap
|
||||||
|
# | exit: Return 1 if the ram is under the requirement, 0 otherwise.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_require_ram () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=rftso
|
||||||
|
local -A args_array=( [r]=required= [f]=free [t]=total [s]=ignore_swap [o]=only_swap )
|
||||||
|
local required
|
||||||
|
local free
|
||||||
|
local total
|
||||||
|
local ignore_swap
|
||||||
|
local only_swap
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
# Dunno if that's the right way to do, but that's some black magic to be able to
|
||||||
|
# forward the bool args to ynh_get_ram easily?
|
||||||
|
# If the variable $free is not empty, set it to '--free'
|
||||||
|
free=${free:+--free}
|
||||||
|
total=${total:+--total}
|
||||||
|
ignore_swap=${ignore_swap:+--ignore_swap}
|
||||||
|
only_swap=${only_swap:+--only_swap}
|
||||||
|
|
||||||
|
local ram=$(ynh_get_ram $free $total $ignore_swap $only_swap)
|
||||||
|
|
||||||
|
if [ $ram -lt $required ]
|
||||||
|
then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
|
@ -3,30 +3,34 @@
|
||||||
# Print a message to stderr and exit
|
# Print a message to stderr and exit
|
||||||
#
|
#
|
||||||
# usage: ynh_die --message=MSG [--ret_code=RETCODE]
|
# usage: ynh_die --message=MSG [--ret_code=RETCODE]
|
||||||
|
# | arg: -m, --message= - Message to display
|
||||||
|
# | arg: -c, --ret_code= - Exit code to exit with
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.4.0 or higher.
|
# Requires YunoHost version 2.4.0 or higher.
|
||||||
ynh_die() {
|
ynh_die() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=mc
|
local legacy_args=mc
|
||||||
declare -Ar args_array=( [m]=message= [c]=ret_code= )
|
local -A args_array=( [m]=message= [c]=ret_code= )
|
||||||
local message
|
local message
|
||||||
local ret_code
|
local ret_code
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
ret_code=${ret_code:-1}
|
||||||
|
|
||||||
echo "$message" 1>&2
|
echo "$message" 1>&2
|
||||||
exit "${ret_code:-1}"
|
exit "$ret_code"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Display a message in the 'INFO' logging category
|
# Display a message in the 'INFO' logging category
|
||||||
#
|
#
|
||||||
# usage: ynh_print_info --message="Some message"
|
# usage: ynh_print_info --message="Some message"
|
||||||
|
# | arg: -m, --message= - Message to display
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_print_info() {
|
ynh_print_info() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=m
|
local legacy_args=m
|
||||||
declare -Ar args_array=( [m]=message= )
|
local -A args_array=( [m]=message= )
|
||||||
local message
|
local message
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
@ -45,12 +49,12 @@ ynh_print_info() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_no_log() {
|
ynh_no_log() {
|
||||||
local ynh_cli_log=/var/log/yunohost/yunohost-cli.log
|
local ynh_cli_log=/var/log/yunohost/yunohost-cli.log
|
||||||
sudo cp -a ${ynh_cli_log} ${ynh_cli_log}-move
|
cp --archive ${ynh_cli_log} ${ynh_cli_log}-move
|
||||||
eval $@
|
eval $@
|
||||||
local exit_code=$?
|
local exit_code=$?
|
||||||
sudo mv ${ynh_cli_log}-move ${ynh_cli_log}
|
mv ${ynh_cli_log}-move ${ynh_cli_log}
|
||||||
return $?
|
return $exit_code
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main printer, just in case in the future we have to change anything about that.
|
# Main printer, just in case in the future we have to change anything about that.
|
||||||
|
@ -59,121 +63,116 @@ ynh_no_log() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_print_log () {
|
ynh_print_log () {
|
||||||
echo -e "${1}"
|
echo -e "${1}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Print a warning on stderr
|
# Print a warning on stderr
|
||||||
#
|
#
|
||||||
# usage: ynh_print_warn --message="Text to print"
|
# usage: ynh_print_warn --message="Text to print"
|
||||||
# | arg: -m, --message - The text to print
|
# | arg: -m, --message= - The text to print
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_print_warn () {
|
ynh_print_warn () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=m
|
local legacy_args=m
|
||||||
declare -Ar args_array=( [m]=message= )
|
local -A args_array=( [m]=message= )
|
||||||
local message
|
local message
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
ynh_print_log "\e[93m\e[1m[WARN]\e[0m ${message}" >&2
|
ynh_print_log "\e[93m\e[1m[WARN]\e[0m ${message}" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
# Print an error on stderr
|
# Print an error on stderr
|
||||||
#
|
#
|
||||||
# usage: ynh_print_err --message="Text to print"
|
# usage: ynh_print_err --message="Text to print"
|
||||||
# | arg: -m, --message - The text to print
|
# | arg: -m, --message= - The text to print
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_print_err () {
|
ynh_print_err () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=m
|
local legacy_args=m
|
||||||
declare -Ar args_array=( [m]=message= )
|
local -A args_array=( [m]=message= )
|
||||||
local message
|
local message
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
ynh_print_log "\e[91m\e[1m[ERR]\e[0m ${message}" >&2
|
ynh_print_log "\e[91m\e[1m[ERR]\e[0m ${message}" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command and print the result as an error
|
# Execute a command and print the result as an error
|
||||||
#
|
#
|
||||||
# usage: ynh_exec_err your_command
|
# usage: ynh_exec_err your_command
|
||||||
# usage: ynh_exec_err "your_command | other_command"
|
# usage: ynh_exec_err "your_command | other_command"
|
||||||
|
# | arg: command - command to execute
|
||||||
#
|
#
|
||||||
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
||||||
#
|
#
|
||||||
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
||||||
#
|
#
|
||||||
# | arg: command - command to execute
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_exec_err () {
|
ynh_exec_err () {
|
||||||
ynh_print_err "$(eval $@)"
|
ynh_print_err "$(eval $@)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command and print the result as a warning
|
# Execute a command and print the result as a warning
|
||||||
#
|
#
|
||||||
# usage: ynh_exec_warn your_command
|
# usage: ynh_exec_warn your_command
|
||||||
# usage: ynh_exec_warn "your_command | other_command"
|
# usage: ynh_exec_warn "your_command | other_command"
|
||||||
|
# | arg: command - command to execute
|
||||||
#
|
#
|
||||||
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
||||||
#
|
#
|
||||||
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
||||||
#
|
#
|
||||||
# | arg: command - command to execute
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_exec_warn () {
|
ynh_exec_warn () {
|
||||||
ynh_print_warn "$(eval $@)"
|
ynh_print_warn "$(eval $@)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command and force the result to be printed on stdout
|
# Execute a command and force the result to be printed on stdout
|
||||||
#
|
#
|
||||||
# usage: ynh_exec_warn_less your_command
|
# usage: ynh_exec_warn_less your_command
|
||||||
# usage: ynh_exec_warn_less "your_command | other_command"
|
# usage: ynh_exec_warn_less "your_command | other_command"
|
||||||
|
# | arg: command - command to execute
|
||||||
#
|
#
|
||||||
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
||||||
#
|
#
|
||||||
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
||||||
#
|
#
|
||||||
# | arg: command - command to execute
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_exec_warn_less () {
|
ynh_exec_warn_less () {
|
||||||
eval $@ 2>&1
|
eval $@ 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command and redirect stdout in /dev/null
|
# Execute a command and redirect stdout in /dev/null
|
||||||
#
|
#
|
||||||
# usage: ynh_exec_quiet your_command
|
# usage: ynh_exec_quiet your_command
|
||||||
# usage: ynh_exec_quiet "your_command | other_command"
|
# usage: ynh_exec_quiet "your_command | other_command"
|
||||||
|
# | arg: command - command to execute
|
||||||
#
|
#
|
||||||
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
||||||
#
|
#
|
||||||
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
||||||
#
|
#
|
||||||
# | arg: command - command to execute
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_exec_quiet () {
|
ynh_exec_quiet () {
|
||||||
eval $@ > /dev/null
|
eval $@ > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command and redirect stdout and stderr in /dev/null
|
# Execute a command and redirect stdout and stderr in /dev/null
|
||||||
#
|
#
|
||||||
# usage: ynh_exec_fully_quiet your_command
|
# usage: ynh_exec_fully_quiet your_command
|
||||||
# usage: ynh_exec_fully_quiet "your_command | other_command"
|
# usage: ynh_exec_fully_quiet "your_command | other_command"
|
||||||
|
# | arg: command - command to execute
|
||||||
#
|
#
|
||||||
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
||||||
#
|
#
|
||||||
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
||||||
#
|
#
|
||||||
# | arg: command - command to execute
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_exec_fully_quiet () {
|
ynh_exec_fully_quiet () {
|
||||||
eval $@ > /dev/null 2>&1
|
eval $@ > /dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove any logs for all the following commands.
|
# Remove any logs for all the following commands.
|
||||||
|
@ -184,7 +183,7 @@ ynh_exec_fully_quiet () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_print_OFF () {
|
ynh_print_OFF () {
|
||||||
exec {BASH_XTRACEFD}>/dev/null
|
exec {BASH_XTRACEFD}>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Restore the logging after ynh_print_OFF
|
# Restore the logging after ynh_print_OFF
|
||||||
|
@ -193,9 +192,9 @@ ynh_print_OFF () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.2.0 or higher.
|
# Requires YunoHost version 3.2.0 or higher.
|
||||||
ynh_print_ON () {
|
ynh_print_ON () {
|
||||||
exec {BASH_XTRACEFD}>&1
|
exec {BASH_XTRACEFD}>&1
|
||||||
# Print an echo only for the log, to be able to know that ynh_print_ON has been called.
|
# Print an echo only for the log, to be able to know that ynh_print_ON has been called.
|
||||||
echo ynh_print_ON > /dev/null
|
echo ynh_print_ON > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Initial definitions for ynh_script_progression
|
# Initial definitions for ynh_script_progression
|
||||||
|
@ -216,86 +215,87 @@ base_time=$(date +%s)
|
||||||
# usage: ynh_script_progression --message=message [--weight=weight] [--time]
|
# usage: ynh_script_progression --message=message [--weight=weight] [--time]
|
||||||
# | arg: -m, --message= - The text to print
|
# | arg: -m, --message= - The text to print
|
||||||
# | arg: -w, --weight= - The weight for this progression. This value is 1 by default. Use a bigger value for a longer part of the script.
|
# | arg: -w, --weight= - The weight for this progression. This value is 1 by default. Use a bigger value for a longer part of the script.
|
||||||
# | arg: -t, --time= - Print the execution time since the last call to this helper. Especially usefull to define weights. The execution time is given for the duration since the previous call. So the weight should be applied to this previous call.
|
# | arg: -t, --time - Print the execution time since the last call to this helper. Especially usefull to define weights. The execution time is given for the duration since the previous call. So the weight should be applied to this previous call.
|
||||||
# | arg: -l, --last= - Use for the last call of the helper, to fill te progression bar.
|
# | arg: -l, --last - Use for the last call of the helper, to fill te progression bar.
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_script_progression () {
|
ynh_script_progression () {
|
||||||
set +x
|
set +o xtrace # set +x
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=mwtl
|
local legacy_args=mwtl
|
||||||
declare -Ar args_array=( [m]=message= [w]=weight= [t]=time [l]=last )
|
local -A args_array=( [m]=message= [w]=weight= [t]=time [l]=last )
|
||||||
local message
|
local message
|
||||||
local weight
|
local weight
|
||||||
local time
|
local time
|
||||||
local last
|
local last
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
set +x
|
# Re-disable xtrace, ynh_handle_getopts_args set it back
|
||||||
weight=${weight:-1}
|
set +o xtrace # set +x
|
||||||
time=${time:-0}
|
weight=${weight:-1}
|
||||||
last=${last:-0}
|
time=${time:-0}
|
||||||
|
last=${last:-0}
|
||||||
|
|
||||||
# Get execution time since the last $base_time
|
# Get execution time since the last $base_time
|
||||||
local exec_time=$(( $(date +%s) - $base_time ))
|
local exec_time=$(( $(date +%s) - $base_time ))
|
||||||
base_time=$(date +%s)
|
base_time=$(date +%s)
|
||||||
|
|
||||||
# Compute $max_progression (if we didn't already)
|
# Compute $max_progression (if we didn't already)
|
||||||
if [ "$max_progression" = -1 ]
|
if [ "$max_progression" = -1 ]
|
||||||
then
|
then
|
||||||
# Get the number of occurrences of 'ynh_script_progression' in the script. Except those are commented.
|
# Get the number of occurrences of 'ynh_script_progression' in the script. Except those are commented.
|
||||||
local helper_calls="$(grep --count "^[^#]*ynh_script_progression" $0)"
|
local helper_calls="$(grep --count "^[^#]*ynh_script_progression" $0)"
|
||||||
# Get the number of call with a weight value
|
# Get the number of call with a weight value
|
||||||
local weight_calls=$(grep --perl-regexp --count "^[^#]*ynh_script_progression.*(--weight|-w )" $0)
|
local weight_calls=$(grep --perl-regexp --count "^[^#]*ynh_script_progression.*(--weight|-w )" $0)
|
||||||
|
|
||||||
# Get the weight of each occurrences of 'ynh_script_progression' in the script using --weight
|
# Get the weight of each occurrences of 'ynh_script_progression' in the script using --weight
|
||||||
local weight_valuesA="$(grep --perl-regexp "^[^#]*ynh_script_progression.*--weight" $0 | sed 's/.*--weight[= ]\([[:digit:]]*\).*/\1/g')"
|
local weight_valuesA="$(grep --perl-regexp "^[^#]*ynh_script_progression.*--weight" $0 | sed 's/.*--weight[= ]\([[:digit:]]*\).*/\1/g')"
|
||||||
# Get the weight of each occurrences of 'ynh_script_progression' in the script using -w
|
# Get the weight of each occurrences of 'ynh_script_progression' in the script using -w
|
||||||
local weight_valuesB="$(grep --perl-regexp "^[^#]*ynh_script_progression.*-w " $0 | sed 's/.*-w[= ]\([[:digit:]]*\).*/\1/g')"
|
local weight_valuesB="$(grep --perl-regexp "^[^#]*ynh_script_progression.*-w " $0 | sed 's/.*-w[= ]\([[:digit:]]*\).*/\1/g')"
|
||||||
# Each value will be on a different line.
|
# Each value will be on a different line.
|
||||||
# Remove each 'end of line' and replace it by a '+' to sum the values.
|
# Remove each 'end of line' and replace it by a '+' to sum the values.
|
||||||
local weight_values=$(( $(echo "$weight_valuesA" | tr '\n' '+') + $(echo "$weight_valuesB" | tr '\n' '+') 0 ))
|
local weight_values=$(( $(echo "$weight_valuesA" | tr '\n' '+') + $(echo "$weight_valuesB" | tr '\n' '+') 0 ))
|
||||||
|
|
||||||
# max_progression is a total number of calls to this helper.
|
# max_progression is a total number of calls to this helper.
|
||||||
# Less the number of calls with a weight value.
|
# Less the number of calls with a weight value.
|
||||||
# Plus the total of weight values
|
# Plus the total of weight values
|
||||||
max_progression=$(( $helper_calls - $weight_calls + $weight_values ))
|
max_progression=$(( $helper_calls - $weight_calls + $weight_values ))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increment each execution of ynh_script_progression in this script by the weight of the previous call.
|
# Increment each execution of ynh_script_progression in this script by the weight of the previous call.
|
||||||
increment_progression=$(( $increment_progression + $previous_weight ))
|
increment_progression=$(( $increment_progression + $previous_weight ))
|
||||||
# Store the weight of the current call in $previous_weight for next call
|
# Store the weight of the current call in $previous_weight for next call
|
||||||
previous_weight=$weight
|
previous_weight=$weight
|
||||||
|
|
||||||
# Reduce $increment_progression to the size of the scale
|
# Reduce $increment_progression to the size of the scale
|
||||||
if [ $last -eq 0 ]
|
if [ $last -eq 0 ]
|
||||||
then
|
then
|
||||||
local effective_progression=$(( $increment_progression * $progress_scale / $max_progression ))
|
local effective_progression=$(( $increment_progression * $progress_scale / $max_progression ))
|
||||||
# If last is specified, fill immediately the progression_bar
|
# If last is specified, fill immediately the progression_bar
|
||||||
else
|
else
|
||||||
local effective_progression=$progress_scale
|
local effective_progression=$progress_scale
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build $progression_bar from progress_string(0,1,2) according to $effective_progression and the weight of the current task
|
# Build $progression_bar from progress_string(0,1,2) according to $effective_progression and the weight of the current task
|
||||||
# expected_progression is the progression expected after the current task
|
# expected_progression is the progression expected after the current task
|
||||||
local expected_progression="$(( ( $increment_progression + $weight ) * $progress_scale / $max_progression - $effective_progression ))"
|
local expected_progression="$(( ( $increment_progression + $weight ) * $progress_scale / $max_progression - $effective_progression ))"
|
||||||
if [ $last -eq 1 ]
|
if [ $last -eq 1 ]
|
||||||
then
|
then
|
||||||
expected_progression=0
|
expected_progression=0
|
||||||
fi
|
fi
|
||||||
# left_progression is the progression not yet done
|
# left_progression is the progression not yet done
|
||||||
local left_progression="$(( $progress_scale - $effective_progression - $expected_progression ))"
|
local left_progression="$(( $progress_scale - $effective_progression - $expected_progression ))"
|
||||||
# Build the progression bar with $effective_progression, work done, $expected_progression, current work and $left_progression, work to be done.
|
# Build the progression bar with $effective_progression, work done, $expected_progression, current work and $left_progression, work to be done.
|
||||||
local progression_bar="${progress_string2:0:$effective_progression}${progress_string1:0:$expected_progression}${progress_string0:0:$left_progression}"
|
local progression_bar="${progress_string2:0:$effective_progression}${progress_string1:0:$expected_progression}${progress_string0:0:$left_progression}"
|
||||||
|
|
||||||
local print_exec_time=""
|
local print_exec_time=""
|
||||||
if [ $time -eq 1 ]
|
if [ $time -eq 1 ]
|
||||||
then
|
then
|
||||||
print_exec_time=" [$(date +%Hh%Mm,%Ss --date="0 + $exec_time sec")]"
|
print_exec_time=" [$(date +%Hh%Mm,%Ss --date="0 + $exec_time sec")]"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ynh_print_info "[$progression_bar] > ${message}${print_exec_time}"
|
ynh_print_info "[$progression_bar] > ${message}${print_exec_time}"
|
||||||
set -x
|
set -o xtrace # set -x
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return data to the Yunohost core for later processing
|
# Return data to the Yunohost core for later processing
|
||||||
|
@ -316,63 +316,62 @@ ynh_return () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_debug () {
|
ynh_debug () {
|
||||||
# Disable set xtrace for the helper itself, to not pollute the debug log
|
# Disable set xtrace for the helper itself, to not pollute the debug log
|
||||||
set +x
|
set +o xtrace # set +x
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=mt
|
local legacy_args=mt
|
||||||
declare -Ar args_array=( [m]=message= [t]=trace= )
|
local -A args_array=( [m]=message= [t]=trace= )
|
||||||
local message
|
local message
|
||||||
local trace
|
local trace
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
# Redisable xtrace, ynh_handle_getopts_args set it back
|
# Re-disable xtrace, ynh_handle_getopts_args set it back
|
||||||
set +x
|
set +o xtrace # set +x
|
||||||
message=${message:-}
|
message=${message:-}
|
||||||
trace=${trace:-}
|
trace=${trace:-}
|
||||||
|
|
||||||
if [ -n "$message" ]
|
if [ -n "$message" ]
|
||||||
then
|
then
|
||||||
ynh_print_log "\e[34m\e[1m[DEBUG]\e[0m ${message}" >&2
|
ynh_print_log "\e[34m\e[1m[DEBUG]\e[0m ${message}" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$trace" == "1" ]
|
if [ "$trace" == "1" ]
|
||||||
then
|
then
|
||||||
ynh_debug --message="Enable debugging"
|
ynh_debug --message="Enable debugging"
|
||||||
set +x
|
set +o xtrace # set +x
|
||||||
# Get the current file descriptor of xtrace
|
# Get the current file descriptor of xtrace
|
||||||
old_bash_xtracefd=$BASH_XTRACEFD
|
old_bash_xtracefd=$BASH_XTRACEFD
|
||||||
# Add the current file name and the line number of any command currently running while tracing.
|
# Add the current file name and the line number of any command currently running while tracing.
|
||||||
PS4='$(basename ${BASH_SOURCE[0]})-L${LINENO}: '
|
PS4='$(basename ${BASH_SOURCE[0]})-L${LINENO}: '
|
||||||
# Force xtrace to stderr
|
# Force xtrace to stderr
|
||||||
BASH_XTRACEFD=2
|
BASH_XTRACEFD=2
|
||||||
# Force stdout to stderr
|
# Force stdout to stderr
|
||||||
exec 1>&2
|
exec 1>&2
|
||||||
fi
|
fi
|
||||||
if [ "$trace" == "0" ]
|
if [ "$trace" == "0" ]
|
||||||
then
|
then
|
||||||
ynh_debug --message="Disable debugging"
|
ynh_debug --message="Disable debugging"
|
||||||
set +x
|
set +o xtrace # set +x
|
||||||
# Put xtrace back to its original fild descriptor
|
# Put xtrace back to its original fild descriptor
|
||||||
BASH_XTRACEFD=$old_bash_xtracefd
|
BASH_XTRACEFD=$old_bash_xtracefd
|
||||||
# Restore stdout
|
# Restore stdout
|
||||||
exec 1>&1
|
exec 1>&1
|
||||||
fi
|
fi
|
||||||
# Renable set xtrace
|
# Renable set xtrace
|
||||||
set -x
|
set -o xtrace # set -x
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command and print the result as debug
|
# Execute a command and print the result as debug
|
||||||
#
|
#
|
||||||
# usage: ynh_debug_exec your_command
|
# usage: ynh_debug_exec your_command
|
||||||
# usage: ynh_debug_exec "your_command | other_command"
|
# usage: ynh_debug_exec "your_command | other_command"
|
||||||
|
# | arg: command - command to execute
|
||||||
#
|
#
|
||||||
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
|
||||||
#
|
#
|
||||||
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
|
||||||
#
|
#
|
||||||
# | arg: command - command to execute
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_debug_exec () {
|
ynh_debug_exec () {
|
||||||
ynh_debug --message="$(eval $@)"
|
ynh_debug --message="$(eval $@)"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
# Use logrotate to manage the logfile
|
# Use logrotate to manage the logfile
|
||||||
#
|
#
|
||||||
# usage: ynh_use_logrotate [--logfile=/log/file] [--nonappend] [--specific_user=user/group]
|
# usage: ynh_use_logrotate [--logfile=/log/file] [--nonappend] [--specific_user=user/group]
|
||||||
# | arg: -l, --logfile - absolute path of logfile
|
# | arg: -l, --logfile= - absolute path of logfile
|
||||||
# | arg: -n, --nonappend - (optional) Replace the config file instead of appending this new config.
|
# | arg: -n, --nonappend - (optional) Replace the config file instead of appending this new config.
|
||||||
# | arg: -u, --specific_user : run logrotate as the specified user and group. If not specified logrotate is runned as root.
|
# | arg: -u, --specific_user= - run logrotate as the specified user and group. If not specified logrotate is runned as root.
|
||||||
#
|
#
|
||||||
# If no --logfile is provided, /var/log/${app} will be used as default.
|
# If no --logfile is provided, /var/log/${app} will be used as default.
|
||||||
# logfile can be just a directory, or a full path to a logfile :
|
# logfile can be just a directory, or a full path to a logfile :
|
||||||
|
@ -16,79 +16,88 @@
|
||||||
# the same logrotate config file. Unless you use the option --non-append
|
# the same logrotate config file. Unless you use the option --non-append
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
# Requires YunoHost version 3.2.0 or higher for the argument --specific_user
|
||||||
ynh_use_logrotate () {
|
ynh_use_logrotate () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=lnuya
|
local legacy_args=lnuya
|
||||||
declare -Ar args_array=( [l]=logfile= [n]=nonappend [u]=specific_user= [y]=non [a]=append )
|
local -A args_array=( [l]=logfile= [n]=nonappend [u]=specific_user= [y]=non [a]=append )
|
||||||
# [y]=non [a]=append are only for legacy purpose, to not fail on the old option '--non-append'
|
# [y]=non [a]=append are only for legacy purpose, to not fail on the old option '--non-append'
|
||||||
local logfile
|
local logfile
|
||||||
local nonappend
|
local nonappend
|
||||||
local specific_user
|
local specific_user
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
local logfile="${logfile:-}"
|
logfile="${logfile:-}"
|
||||||
local nonappend="${nonappend:-0}"
|
nonappend="${nonappend:-0}"
|
||||||
local specific_user="${specific_user:-}"
|
specific_user="${specific_user:-}"
|
||||||
|
|
||||||
# LEGACY CODE - PRE GETOPTS
|
# LEGACY CODE - PRE GETOPTS
|
||||||
if [ $# -gt 0 ] && [ "$1" == "--non-append" ]; then
|
if [ $# -gt 0 ] && [ "$1" == "--non-append" ]
|
||||||
nonappend=1
|
then
|
||||||
# Destroy this argument for the next command.
|
nonappend=1
|
||||||
shift
|
# Destroy this argument for the next command.
|
||||||
elif [ $# -gt 1 ] && [ "$2" == "--non-append" ]; then
|
shift
|
||||||
nonappend=1
|
elif [ $# -gt 1 ] && [ "$2" == "--non-append" ]
|
||||||
fi
|
then
|
||||||
|
nonappend=1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $# -gt 0 ] && [ "$(echo ${1:0:1})" != "-" ]; then
|
if [ $# -gt 0 ] && [ "$(echo ${1:0:1})" != "-" ]
|
||||||
if [ "$(echo ${1##*.})" == "log" ]; then # Keep only the extension to check if it's a logfile
|
then
|
||||||
local logfile=$1 # In this case, focus logrotate on the logfile
|
# If the given logfile parameter already exists as a file, or if it ends up with ".log",
|
||||||
else
|
# we just want to manage a single file
|
||||||
local logfile=$1/*.log # Else, uses the directory and all logfile into it.
|
if [ -f "$1" ] || [ "$(echo ${1##*.})" == "log" ]
|
||||||
fi
|
then
|
||||||
fi
|
local logfile=$1
|
||||||
# LEGACY CODE
|
# Otherwise we assume we want to manage a directory and all its .log file inside
|
||||||
|
else
|
||||||
|
local logfile=$1/*.log
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# LEGACY CODE
|
||||||
|
|
||||||
local customtee="tee -a"
|
local customtee="tee --append"
|
||||||
if [ "$nonappend" -eq 1 ]; then
|
if [ "$nonappend" -eq 1 ]; then
|
||||||
customtee="tee"
|
customtee="tee"
|
||||||
fi
|
fi
|
||||||
if [ -n "$logfile" ]
|
if [ -n "$logfile" ]
|
||||||
then
|
then
|
||||||
if [ "$(echo ${logfile##*.})" != "log" ]; then # Keep only the extension to check if it's a logfile
|
if [ ! -f "$1" ] && [ "$(echo ${logfile##*.})" != "log" ]; then # Keep only the extension to check if it's a logfile
|
||||||
local logfile="$logfile/*.log" # Else, uses the directory and all logfile into it.
|
local logfile="$logfile/*.log" # Else, uses the directory and all logfile into it.
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log
|
logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log
|
||||||
fi
|
fi
|
||||||
local su_directive=""
|
local su_directive=""
|
||||||
if [[ -n $specific_user ]]; then
|
if [[ -n $specific_user ]]
|
||||||
su_directive=" # Run logorotate as specific user - group
|
then
|
||||||
su ${specific_user%/*} ${specific_user#*/}"
|
su_directive=" # Run logorotate as specific user - group
|
||||||
fi
|
su ${specific_user%/*} ${specific_user#*/}"
|
||||||
|
fi
|
||||||
|
|
||||||
cat > ./${app}-logrotate << EOF # Build a config file for logrotate
|
cat > ./${app}-logrotate << EOF # Build a config file for logrotate
|
||||||
$logfile {
|
$logfile {
|
||||||
# Rotate if the logfile exceeds 100Mo
|
# Rotate if the logfile exceeds 100Mo
|
||||||
size 100M
|
size 100M
|
||||||
# Keep 12 old log maximum
|
# Keep 12 old log maximum
|
||||||
rotate 12
|
rotate 12
|
||||||
# Compress the logs with gzip
|
# Compress the logs with gzip
|
||||||
compress
|
compress
|
||||||
# Compress the log at the next cycle. So keep always 2 non compressed logs
|
# Compress the log at the next cycle. So keep always 2 non compressed logs
|
||||||
delaycompress
|
delaycompress
|
||||||
# Copy and truncate the log to allow to continue write on it. Instead of move the log.
|
# Copy and truncate the log to allow to continue write on it. Instead of move the log.
|
||||||
copytruncate
|
copytruncate
|
||||||
# Do not do an error if the log is missing
|
# Do not do an error if the log is missing
|
||||||
missingok
|
missingok
|
||||||
# Not rotate if the log is empty
|
# Not rotate if the log is empty
|
||||||
notifempty
|
notifempty
|
||||||
# Keep old logs in the same dir
|
# Keep old logs in the same dir
|
||||||
noolddir
|
noolddir
|
||||||
$su_directive
|
$su_directive
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
sudo mkdir -p $(dirname "$logfile") # Create the log directory, if not exist
|
mkdir --parents $(dirname "$logfile") # Create the log directory, if not exist
|
||||||
cat ${app}-logrotate | sudo $customtee /etc/logrotate.d/$app > /dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee)
|
cat ${app}-logrotate | $customtee /etc/logrotate.d/$app > /dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove the app's logrotate config.
|
# Remove the app's logrotate config.
|
||||||
|
@ -97,7 +106,7 @@ EOF
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_remove_logrotate () {
|
ynh_remove_logrotate () {
|
||||||
if [ -e "/etc/logrotate.d/$app" ]; then
|
if [ -e "/etc/logrotate.d/$app" ]; then
|
||||||
sudo rm "/etc/logrotate.d/$app"
|
rm "/etc/logrotate.d/$app"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,19 +4,19 @@ MYSQL_ROOT_PWD_FILE=/etc/yunohost/mysql
|
||||||
|
|
||||||
# Open a connection as a user
|
# Open a connection as a user
|
||||||
#
|
#
|
||||||
# example: ynh_mysql_connect_as 'user' 'pass' <<< "UPDATE ...;"
|
# example: ynh_mysql_connect_as --user="user" --password="pass" <<< "UPDATE ...;"
|
||||||
# example: ynh_mysql_connect_as 'user' 'pass' < /path/to/file.sql
|
# example: ynh_mysql_connect_as --user="user" --password="pass" < /path/to/file.sql
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_connect_as --user=user --password=password [--database=database]
|
# usage: ynh_mysql_connect_as --user=user --password=password [--database=database]
|
||||||
# | arg: -u, --user - the user name to connect as
|
# | arg: -u, --user= - the user name to connect as
|
||||||
# | arg: -p, --password - the user password
|
# | arg: -p, --password= - the user password
|
||||||
# | arg: -d, --database - the database to connect to
|
# | arg: -d, --database= - the database to connect to
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_mysql_connect_as() {
|
ynh_mysql_connect_as() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=upd
|
local legacy_args=upd
|
||||||
declare -Ar args_array=( [u]=user= [p]=password= [d]=database= )
|
local -A args_array=( [u]=user= [p]=password= [d]=database= )
|
||||||
local user
|
local user
|
||||||
local password
|
local password
|
||||||
local database
|
local database
|
||||||
|
@ -24,48 +24,48 @@ ynh_mysql_connect_as() {
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
database="${database:-}"
|
database="${database:-}"
|
||||||
|
|
||||||
mysql -u "$user" --password="$password" -B "$database"
|
mysql --user="$user" --password="$password" --batch "$database"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command as root user
|
# Execute a command as root user
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_execute_as_root --sql=sql [--database=database]
|
# usage: ynh_mysql_execute_as_root --sql=sql [--database=database]
|
||||||
# | arg: -s, --sql - the SQL command to execute
|
# | arg: -s, --sql= - the SQL command to execute
|
||||||
# | arg: -d, --database - the database to connect to
|
# | arg: -d, --database= - the database to connect to
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_mysql_execute_as_root() {
|
ynh_mysql_execute_as_root() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=sd
|
local legacy_args=sd
|
||||||
declare -Ar args_array=( [s]=sql= [d]=database= )
|
local -A args_array=( [s]=sql= [d]=database= )
|
||||||
local sql
|
local sql
|
||||||
local database
|
local database
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
database="${database:-}"
|
database="${database:-}"
|
||||||
|
|
||||||
ynh_mysql_connect_as --user="root" --password="$(sudo cat $MYSQL_ROOT_PWD_FILE)" \
|
ynh_mysql_connect_as --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" \
|
||||||
--database="$database" <<< "$sql"
|
--database="$database" <<< "$sql"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command from a file as root user
|
# Execute a command from a file as root user
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_execute_file_as_root --file=file [--database=database]
|
# usage: ynh_mysql_execute_file_as_root --file=file [--database=database]
|
||||||
# | arg: -f, --file - the file containing SQL commands
|
# | arg: -f, --file= - the file containing SQL commands
|
||||||
# | arg: -d, --database - the database to connect to
|
# | arg: -d, --database= - the database to connect to
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_mysql_execute_file_as_root() {
|
ynh_mysql_execute_file_as_root() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=fd
|
local legacy_args=fd
|
||||||
declare -Ar args_array=( [f]=file= [d]=database= )
|
local -A args_array=( [f]=file= [d]=database= )
|
||||||
local file
|
local file
|
||||||
local database
|
local database
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
database="${database:-}"
|
database="${database:-}"
|
||||||
|
|
||||||
ynh_mysql_connect_as --user="root" --password="$(sudo cat $MYSQL_ROOT_PWD_FILE)" \
|
ynh_mysql_connect_as --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" \
|
||||||
--database="$database" < "$file"
|
--database="$database" < "$file"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,9 +85,12 @@ ynh_mysql_create_db() {
|
||||||
local sql="CREATE DATABASE ${db};"
|
local sql="CREATE DATABASE ${db};"
|
||||||
|
|
||||||
# grant all privilegies to user
|
# grant all privilegies to user
|
||||||
if [[ $# -gt 1 ]]; then
|
if [[ $# -gt 1 ]]
|
||||||
|
then
|
||||||
sql+=" GRANT ALL PRIVILEGES ON ${db}.* TO '${2}'@'localhost'"
|
sql+=" GRANT ALL PRIVILEGES ON ${db}.* TO '${2}'@'localhost'"
|
||||||
[[ -n ${3:-} ]] && sql+=" IDENTIFIED BY '${3}'"
|
if [[ -n ${3:-} ]]; then
|
||||||
|
sql+=" IDENTIFIED BY '${3}'"
|
||||||
|
fi
|
||||||
sql+=" WITH GRANT OPTION;"
|
sql+=" WITH GRANT OPTION;"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -111,22 +114,22 @@ ynh_mysql_drop_db() {
|
||||||
|
|
||||||
# Dump a database
|
# Dump a database
|
||||||
#
|
#
|
||||||
# example: ynh_mysql_dump_db 'roundcube' > ./dump.sql
|
# example: ynh_mysql_dump_db --database=roundcube > ./dump.sql
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_dump_db --database=database
|
# usage: ynh_mysql_dump_db --database=database
|
||||||
# | arg: -d, --database - the database name to dump
|
# | arg: -d, --database= - the database name to dump
|
||||||
# | ret: the mysqldump output
|
# | ret: the mysqldump output
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_mysql_dump_db() {
|
ynh_mysql_dump_db() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=d
|
local legacy_args=d
|
||||||
declare -Ar args_array=( [d]=database= )
|
local -A args_array=( [d]=database= )
|
||||||
local database
|
local database
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
mysqldump -u "root" -p"$(sudo cat $MYSQL_ROOT_PWD_FILE)" --single-transaction --skip-dump-date "$database"
|
mysqldump --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" --single-transaction --skip-dump-date "$database"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a user
|
# Create a user
|
||||||
|
@ -146,24 +149,25 @@ ynh_mysql_create_user() {
|
||||||
# Check if a mysql user exists
|
# Check if a mysql user exists
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_user_exists --user=user
|
# usage: ynh_mysql_user_exists --user=user
|
||||||
# | arg: -u, --user - the user for which to check existence
|
# | arg: -u, --user= - the user for which to check existence
|
||||||
|
# | exit: Return 1 if the user doesn't exist, 0 otherwise.
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_mysql_user_exists()
|
ynh_mysql_user_exists()
|
||||||
{
|
{
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=u
|
local legacy_args=u
|
||||||
declare -Ar args_array=( [u]=user= )
|
local -A args_array=( [u]=user= )
|
||||||
local user
|
local user
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
if [[ -z $(ynh_mysql_execute_as_root --sql="SELECT User from mysql.user WHERE User = '$user';") ]]
|
if [[ -z $(ynh_mysql_execute_as_root --sql="SELECT User from mysql.user WHERE User = '$user';") ]]
|
||||||
then
|
then
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Drop a user
|
# Drop a user
|
||||||
|
@ -180,59 +184,59 @@ ynh_mysql_drop_user() {
|
||||||
|
|
||||||
# Create a database, an user and its password. Then store the password in the app's config
|
# Create a database, an user and its password. Then store the password in the app's config
|
||||||
#
|
#
|
||||||
|
# usage: ynh_mysql_setup_db --db_user=user --db_name=name [--db_pwd=pwd]
|
||||||
|
# | arg: -u, --db_user= - Owner of the database
|
||||||
|
# | arg: -n, --db_name= - Name of the database
|
||||||
|
# | arg: -p, --db_pwd= - Password of the database. If not provided, a password will be generated
|
||||||
|
#
|
||||||
# After executing this helper, the password of the created database will be available in $db_pwd
|
# After executing this helper, the password of the created database will be available in $db_pwd
|
||||||
# It will also be stored as "mysqlpwd" into the app settings.
|
# It will also be stored as "mysqlpwd" into the app settings.
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_setup_db --db_user=user --db_name=name [--db_pwd=pwd]
|
|
||||||
# | arg: -u, --db_user - Owner of the database
|
|
||||||
# | arg: -n, --db_name - Name of the database
|
|
||||||
# | arg: -p, --db_pwd - Password of the database. If not provided, a password will be generated
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_mysql_setup_db () {
|
ynh_mysql_setup_db () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=unp
|
local legacy_args=unp
|
||||||
declare -Ar args_array=( [u]=db_user= [n]=db_name= [p]=db_pwd= )
|
local -A args_array=( [u]=db_user= [n]=db_name= [p]=db_pwd= )
|
||||||
local db_user
|
local db_user
|
||||||
local db_name
|
local db_name
|
||||||
db_pwd=""
|
db_pwd=""
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
local new_db_pwd=$(ynh_string_random) # Generate a random password
|
local new_db_pwd=$(ynh_string_random) # Generate a random password
|
||||||
# If $db_pwd is not provided, use new_db_pwd instead for db_pwd
|
# If $db_pwd is not provided, use new_db_pwd instead for db_pwd
|
||||||
db_pwd="${db_pwd:-$new_db_pwd}"
|
db_pwd="${db_pwd:-$new_db_pwd}"
|
||||||
|
|
||||||
ynh_mysql_create_db "$db_name" "$db_user" "$db_pwd" # Create the database
|
ynh_mysql_create_db "$db_name" "$db_user" "$db_pwd" # Create the database
|
||||||
ynh_app_setting_set --app=$app --key=mysqlpwd --value=$db_pwd # Store the password in the app's config
|
ynh_app_setting_set --app=$app --key=mysqlpwd --value=$db_pwd # Store the password in the app's config
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove a database if it exists, and the associated user
|
# Remove a database if it exists, and the associated user
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_remove_db --db_user=user --db_name=name
|
# usage: ynh_mysql_remove_db --db_user=user --db_name=name
|
||||||
# | arg: -u, --db_user - Owner of the database
|
# | arg: -u, --db_user= - Owner of the database
|
||||||
# | arg: -n, --db_name - Name of the database
|
# | arg: -n, --db_name= - Name of the database
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_mysql_remove_db () {
|
ynh_mysql_remove_db () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=un
|
local legacy_args=un
|
||||||
declare -Ar args_array=( [u]=db_user= [n]=db_name= )
|
local -A args_array=( [u]=db_user= [n]=db_name= )
|
||||||
local db_user
|
local db_user
|
||||||
local db_name
|
local db_name
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
local mysql_root_password=$(sudo cat $MYSQL_ROOT_PWD_FILE)
|
local mysql_root_password=$(cat $MYSQL_ROOT_PWD_FILE)
|
||||||
if mysqlshow -u root -p$mysql_root_password | grep -q "^| $db_name"; then # Check if the database exists
|
if mysqlshow --user=root --password=$mysql_root_password | grep --quiet "^| $db_name"
|
||||||
ynh_mysql_drop_db $db_name # Remove the database
|
then # Check if the database exists
|
||||||
else
|
ynh_mysql_drop_db $db_name # Remove the database
|
||||||
ynh_print_warn --message="Database $db_name not found"
|
else
|
||||||
fi
|
ynh_print_warn --message="Database $db_name not found"
|
||||||
|
fi
|
||||||
|
|
||||||
# Remove mysql user if it exists
|
# Remove mysql user if it exists
|
||||||
if ynh_mysql_user_exists --user=$db_user; then
|
if ynh_mysql_user_exists --user=$db_user; then
|
||||||
ynh_mysql_drop_user $db_user
|
ynh_mysql_drop_user $db_user
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,27 +5,56 @@
|
||||||
# example: port=$(ynh_find_port --port=8080)
|
# example: port=$(ynh_find_port --port=8080)
|
||||||
#
|
#
|
||||||
# usage: ynh_find_port --port=begin_port
|
# usage: ynh_find_port --port=begin_port
|
||||||
# | arg: -p, --port - port to start to search
|
# | arg: -p, --port= - port to start to search
|
||||||
|
# | ret: the port number
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_find_port () {
|
ynh_find_port () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=p
|
local legacy_args=p
|
||||||
declare -Ar args_array=( [p]=port= )
|
local -A args_array=( [p]=port= )
|
||||||
local port
|
local port
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
test -n "$port" || ynh_die --message="The argument of ynh_find_port must be a valid port."
|
test -n "$port" || ynh_die --message="The argument of ynh_find_port must be a valid port."
|
||||||
while netcat -z 127.0.0.1 $port # Check if the port is free
|
while ! ynh_port_available --port=$port
|
||||||
do
|
do
|
||||||
port=$((port+1)) # Else, pass to next port
|
port=$((port+1)) # Else, pass to next port
|
||||||
done
|
done
|
||||||
echo $port
|
echo $port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Test if a port is available
|
||||||
|
#
|
||||||
|
# example: ynh_port_available --port=1234 || ynh_die "Port 1234 is needs to be available for this app"
|
||||||
|
#
|
||||||
|
# usage: ynh_find_port --port=XYZ
|
||||||
|
# | arg: -p, --port= - port to check
|
||||||
|
# | exit: Return 1 if the port is already used by another process.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.0 or higher.
|
||||||
|
ynh_port_available () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=p
|
||||||
|
local -A args_array=( [p]=port= )
|
||||||
|
local port
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
if ss --numeric --listening --tcp --udp | awk '{print$5}' | grep --quiet --extended-regexp ":$port$" # Check if the port is free
|
||||||
|
then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Validate an IP address
|
# Validate an IP address
|
||||||
#
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
# usage: ynh_validate_ip --family=family --ip_address=ip_address
|
# usage: ynh_validate_ip --family=family --ip_address=ip_address
|
||||||
# | ret: 0 for valid ip addresses, 1 otherwise
|
# | ret: 0 for valid ip addresses, 1 otherwise
|
||||||
#
|
#
|
||||||
|
@ -34,17 +63,17 @@ ynh_find_port () {
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_validate_ip()
|
ynh_validate_ip()
|
||||||
{
|
{
|
||||||
# http://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python#319298
|
# http://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python#319298
|
||||||
|
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=fi
|
local legacy_args=fi
|
||||||
declare -Ar args_array=( [f]=family= [i]=ip_address= )
|
local -A args_array=( [f]=family= [i]=ip_address= )
|
||||||
local family
|
local family
|
||||||
local ip_address
|
local ip_address
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
[ "$family" == "4" ] || [ "$family" == "6" ] || return 1
|
[ "$family" == "4" ] || [ "$family" == "6" ] || return 1
|
||||||
|
|
||||||
python /dev/stdin << EOF
|
python /dev/stdin << EOF
|
||||||
import socket
|
import socket
|
||||||
|
@ -63,19 +92,20 @@ EOF
|
||||||
# example: ynh_validate_ip4 111.222.333.444
|
# example: ynh_validate_ip4 111.222.333.444
|
||||||
#
|
#
|
||||||
# usage: ynh_validate_ip4 --ip_address=ip_address
|
# usage: ynh_validate_ip4 --ip_address=ip_address
|
||||||
|
# | arg: -i, --ip_address= - the ipv4 address to check
|
||||||
# | ret: 0 for valid ipv4 addresses, 1 otherwise
|
# | ret: 0 for valid ipv4 addresses, 1 otherwise
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_validate_ip4()
|
ynh_validate_ip4()
|
||||||
{
|
{
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=i
|
local legacy_args=i
|
||||||
declare -Ar args_array=( [i]=ip_address= )
|
local -A args_array=( [i]=ip_address= )
|
||||||
local ip_address
|
local ip_address
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
ynh_validate_ip 4 $ip_address
|
ynh_validate_ip --family=4 --ip_address=$ip_address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,17 +114,18 @@ ynh_validate_ip4()
|
||||||
# example: ynh_validate_ip6 2000:dead:beef::1
|
# example: ynh_validate_ip6 2000:dead:beef::1
|
||||||
#
|
#
|
||||||
# usage: ynh_validate_ip6 --ip_address=ip_address
|
# usage: ynh_validate_ip6 --ip_address=ip_address
|
||||||
|
# | arg: -i, --ip_address= - the ipv6 address to check
|
||||||
# | ret: 0 for valid ipv6 addresses, 1 otherwise
|
# | ret: 0 for valid ipv6 addresses, 1 otherwise
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_validate_ip6()
|
ynh_validate_ip6()
|
||||||
{
|
{
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=i
|
local legacy_args=i
|
||||||
declare -Ar args_array=( [i]=ip_address= )
|
local -A args_array=( [i]=ip_address= )
|
||||||
local ip_address
|
local ip_address
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
ynh_validate_ip 6 $ip_address
|
ynh_validate_ip --family=6 --ip_address=$ip_address
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,57 +12,61 @@
|
||||||
# __PORT__ by $port
|
# __PORT__ by $port
|
||||||
# __NAME__ by $app
|
# __NAME__ by $app
|
||||||
# __FINALPATH__ by $final_path
|
# __FINALPATH__ by $final_path
|
||||||
|
# __PHPVERSION__ by $YNH_PHP_VERSION ($YNH_PHP_VERSION is either the default php version or the version defined for the app)
|
||||||
#
|
#
|
||||||
# And dynamic variables (from the last example) :
|
# And dynamic variables (from the last example) :
|
||||||
# __PATH_2__ by $path_2
|
# __PATH_2__ by $path_2
|
||||||
# __PORT_2__ by $port_2
|
# __PORT_2__ by $port_2
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
|
# Requires YunoHost version 2.7.13 or higher for dynamic variables
|
||||||
ynh_add_nginx_config () {
|
ynh_add_nginx_config () {
|
||||||
finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
|
finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
local others_var=${1:-}
|
local others_var=${1:-}
|
||||||
ynh_backup_if_checksum_is_different --file="$finalnginxconf"
|
ynh_backup_if_checksum_is_different --file="$finalnginxconf"
|
||||||
sudo cp ../conf/nginx.conf "$finalnginxconf"
|
cp ../conf/nginx.conf "$finalnginxconf"
|
||||||
|
|
||||||
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
||||||
# Substitute in a nginx config file only if the variable is not empty
|
# Substitute in a nginx config file only if the variable is not empty
|
||||||
if test -n "${path_url:-}"; then
|
if test -n "${path_url:-}"
|
||||||
# path_url_slash_less is path_url, or a blank value if path_url is only '/'
|
then
|
||||||
local path_url_slash_less=${path_url%/}
|
# path_url_slash_less is path_url, or a blank value if path_url is only '/'
|
||||||
ynh_replace_string --match_string="__PATH__/" --replace_string="$path_url_slash_less/" --target_file="$finalnginxconf"
|
local path_url_slash_less=${path_url%/}
|
||||||
ynh_replace_string --match_string="__PATH__" --replace_string="$path_url" --target_file="$finalnginxconf"
|
ynh_replace_string --match_string="__PATH__/" --replace_string="$path_url_slash_less/" --target_file="$finalnginxconf"
|
||||||
fi
|
ynh_replace_string --match_string="__PATH__" --replace_string="$path_url" --target_file="$finalnginxconf"
|
||||||
if test -n "${domain:-}"; then
|
fi
|
||||||
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$finalnginxconf"
|
if test -n "${domain:-}"; then
|
||||||
fi
|
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$finalnginxconf"
|
||||||
if test -n "${port:-}"; then
|
fi
|
||||||
ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$finalnginxconf"
|
if test -n "${port:-}"; then
|
||||||
fi
|
ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$finalnginxconf"
|
||||||
if test -n "${app:-}"; then
|
fi
|
||||||
ynh_replace_string --match_string="__NAME__" --replace_string="$app" --target_file="$finalnginxconf"
|
if test -n "${app:-}"; then
|
||||||
fi
|
ynh_replace_string --match_string="__NAME__" --replace_string="$app" --target_file="$finalnginxconf"
|
||||||
if test -n "${final_path:-}"; then
|
fi
|
||||||
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalnginxconf"
|
if test -n "${final_path:-}"; then
|
||||||
fi
|
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalnginxconf"
|
||||||
|
fi
|
||||||
|
ynh_replace_string --match_string="__PHPVERSION__" --replace_string="$YNH_PHP_VERSION" --target_file="$finalnginxconf"
|
||||||
|
|
||||||
# Replace all other variable given as arguments
|
# Replace all other variable given as arguments
|
||||||
for var_to_replace in $others_var
|
for var_to_replace in $others_var
|
||||||
do
|
do
|
||||||
# ${var_to_replace^^} make the content of the variable on upper-cases
|
# ${var_to_replace^^} make the content of the variable on upper-cases
|
||||||
# ${!var_to_replace} get the content of the variable named $var_to_replace
|
# ${!var_to_replace} get the content of the variable named $var_to_replace
|
||||||
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalnginxconf"
|
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalnginxconf"
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "${path_url:-}" != "/" ]
|
|
||||||
then
|
|
||||||
ynh_replace_string --match_string="^#sub_path_only" --replace_string="" --target_file="$finalnginxconf"
|
|
||||||
else
|
|
||||||
ynh_replace_string --match_string="^#root_path_only" --replace_string="" --target_file="$finalnginxconf"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_store_file_checksum --file="$finalnginxconf"
|
if [ "${path_url:-}" != "/" ]
|
||||||
|
then
|
||||||
|
ynh_replace_string --match_string="^#sub_path_only" --replace_string="" --target_file="$finalnginxconf"
|
||||||
|
else
|
||||||
|
ynh_replace_string --match_string="^#root_path_only" --replace_string="" --target_file="$finalnginxconf"
|
||||||
|
fi
|
||||||
|
|
||||||
ynh_systemd_action --service_name=nginx --action=reload
|
ynh_store_file_checksum --file="$finalnginxconf"
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name=nginx --action=reload
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove the dedicated nginx config
|
# Remove the dedicated nginx config
|
||||||
|
@ -71,6 +75,6 @@ ynh_add_nginx_config () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
ynh_remove_nginx_config () {
|
ynh_remove_nginx_config () {
|
||||||
ynh_secure_remove --file="/etc/nginx/conf.d/$domain.d/$app.conf"
|
ynh_secure_remove --file="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
ynh_systemd_action --service_name=nginx --action=reload
|
ynh_systemd_action --service_name=nginx --action=reload
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,16 @@ export N_PREFIX="$n_install_dir"
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
# Requires YunoHost version 2.7.12 or higher.
|
||||||
ynh_install_n () {
|
ynh_install_n () {
|
||||||
ynh_print_info --message="Installation of N - Node.js version management"
|
ynh_print_info --message="Installation of N - Node.js version management"
|
||||||
# Build an app.src for n
|
# Build an app.src for n
|
||||||
mkdir -p "../conf"
|
mkdir --parents "../conf"
|
||||||
echo "SOURCE_URL=https://github.com/tj/n/archive/v4.1.0.tar.gz
|
echo "SOURCE_URL=https://github.com/tj/n/archive/v4.1.0.tar.gz
|
||||||
SOURCE_SUM=3983fa3f00d4bf85ba8e21f1a590f6e28938093abe0bb950aeea52b1717471fc" > "../conf/n.src"
|
SOURCE_SUM=3983fa3f00d4bf85ba8e21f1a590f6e28938093abe0bb950aeea52b1717471fc" > "../conf/n.src"
|
||||||
# Download and extract n
|
# Download and extract n
|
||||||
ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n
|
ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n
|
||||||
# Install n
|
# Install n
|
||||||
(cd "$n_install_dir/git"
|
(cd "$n_install_dir/git"
|
||||||
PREFIX=$N_PREFIX make install 2>&1)
|
PREFIX=$N_PREFIX make install 2>&1)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load the version of node for an app, and set variables.
|
# Load the version of node for an app, and set variables.
|
||||||
|
@ -41,95 +41,97 @@ SOURCE_SUM=3983fa3f00d4bf85ba8e21f1a590f6e28938093abe0bb950aeea52b1717471fc" > "
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
# Requires YunoHost version 2.7.12 or higher.
|
||||||
ynh_use_nodejs () {
|
ynh_use_nodejs () {
|
||||||
nodejs_version=$(ynh_app_setting_get --app=$app --key=nodejs_version)
|
nodejs_version=$(ynh_app_setting_get --app=$app --key=nodejs_version)
|
||||||
|
|
||||||
nodejs_use_version="echo \"Deprecated command, should be removed\""
|
nodejs_use_version="echo \"Deprecated command, should be removed\""
|
||||||
|
|
||||||
# Get the absolute path of this version of node
|
# Get the absolute path of this version of node
|
||||||
nodejs_path="$node_version_path/$nodejs_version/bin"
|
nodejs_path="$node_version_path/$nodejs_version/bin"
|
||||||
|
|
||||||
# Load the path of this version of node in $PATH
|
# Load the path of this version of node in $PATH
|
||||||
[[ :$PATH: == *":$nodejs_path"* ]] || PATH="$nodejs_path:$PATH"
|
if [[ :$PATH: != *":$nodejs_path"* ]]; then
|
||||||
|
PATH="$nodejs_path:$PATH"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install a specific version of nodejs
|
# Install a specific version of nodejs
|
||||||
#
|
#
|
||||||
# n (Node version management) uses the PATH variable to store the path of the version of node it is going to use.
|
|
||||||
# That's how it changes the version
|
|
||||||
#
|
|
||||||
# ynh_install_nodejs will install the version of node provided as argument by using n.
|
# ynh_install_nodejs will install the version of node provided as argument by using n.
|
||||||
#
|
#
|
||||||
# usage: ynh_install_nodejs --nodejs_version=nodejs_version
|
# usage: ynh_install_nodejs --nodejs_version=nodejs_version
|
||||||
# | arg: -n, --nodejs_version - Version of node to install. When possible, your should prefer to use major version number (e.g. 8 instead of 8.10.0). The crontab will then handle the update of minor versions when needed.
|
# | arg: -n, --nodejs_version= - Version of node to install. When possible, your should prefer to use major version number (e.g. 8 instead of 8.10.0). The crontab will then handle the update of minor versions when needed.
|
||||||
|
#
|
||||||
|
# n (Node version management) uses the PATH variable to store the path of the version of node it is going to use.
|
||||||
|
# That's how it changes the version
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
# Requires YunoHost version 2.7.12 or higher.
|
||||||
ynh_install_nodejs () {
|
ynh_install_nodejs () {
|
||||||
# Use n, https://github.com/tj/n to manage the nodejs versions
|
# Use n, https://github.com/tj/n to manage the nodejs versions
|
||||||
|
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=n
|
local legacy_args=n
|
||||||
declare -Ar args_array=( [n]=nodejs_version= )
|
local -A args_array=( [n]=nodejs_version= )
|
||||||
local nodejs_version
|
local nodejs_version
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
# Create $n_install_dir
|
# Create $n_install_dir
|
||||||
mkdir -p "$n_install_dir"
|
mkdir --parents "$n_install_dir"
|
||||||
|
|
||||||
# Load n path in PATH
|
# Load n path in PATH
|
||||||
CLEAR_PATH="$n_install_dir/bin:$PATH"
|
CLEAR_PATH="$n_install_dir/bin:$PATH"
|
||||||
# Remove /usr/local/bin in PATH in case of node prior installation
|
# Remove /usr/local/bin in PATH in case of node prior installation
|
||||||
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
||||||
|
|
||||||
# Move an existing node binary, to avoid to block n.
|
# Move an existing node binary, to avoid to block n.
|
||||||
test -x /usr/bin/node && mv /usr/bin/node /usr/bin/node_n
|
test -x /usr/bin/node && mv /usr/bin/node /usr/bin/node_n
|
||||||
test -x /usr/bin/npm && mv /usr/bin/npm /usr/bin/npm_n
|
test -x /usr/bin/npm && mv /usr/bin/npm /usr/bin/npm_n
|
||||||
|
|
||||||
# If n is not previously setup, install it
|
# If n is not previously setup, install it
|
||||||
if ! test $(n --version > /dev/null 2>&1)
|
if ! test $(n --version > /dev/null 2>&1)
|
||||||
then
|
then
|
||||||
ynh_install_n
|
ynh_install_n
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Modify the default N_PREFIX in n script
|
# Modify the default N_PREFIX in n script
|
||||||
ynh_replace_string --match_string="^N_PREFIX=\${N_PREFIX-.*}$" --replace_string="N_PREFIX=\${N_PREFIX-$N_PREFIX}" --target_file="$n_install_dir/bin/n"
|
ynh_replace_string --match_string="^N_PREFIX=\${N_PREFIX-.*}$" --replace_string="N_PREFIX=\${N_PREFIX-$N_PREFIX}" --target_file="$n_install_dir/bin/n"
|
||||||
|
|
||||||
# Restore /usr/local/bin in PATH
|
# Restore /usr/local/bin in PATH
|
||||||
PATH=$CLEAR_PATH
|
PATH=$CLEAR_PATH
|
||||||
|
|
||||||
# And replace the old node binary.
|
# And replace the old node binary.
|
||||||
test -x /usr/bin/node_n && mv /usr/bin/node_n /usr/bin/node
|
test -x /usr/bin/node_n && mv /usr/bin/node_n /usr/bin/node
|
||||||
test -x /usr/bin/npm_n && mv /usr/bin/npm_n /usr/bin/npm
|
test -x /usr/bin/npm_n && mv /usr/bin/npm_n /usr/bin/npm
|
||||||
|
|
||||||
# Install the requested version of nodejs
|
# Install the requested version of nodejs
|
||||||
uname=$(uname -m)
|
uname=$(uname --machine)
|
||||||
if [[ $uname =~ aarch64 || $uname =~ arm64 ]]
|
if [[ $uname =~ aarch64 || $uname =~ arm64 ]]
|
||||||
then
|
then
|
||||||
n $nodejs_version --arch=arm64
|
n $nodejs_version --arch=arm64
|
||||||
else
|
else
|
||||||
n $nodejs_version
|
n $nodejs_version
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Find the last "real" version for this major version of node.
|
# Find the last "real" version for this major version of node.
|
||||||
real_nodejs_version=$(find $node_version_path/$nodejs_version* -maxdepth 0 | sort --version-sort | tail --lines=1)
|
real_nodejs_version=$(find $node_version_path/$nodejs_version* -maxdepth 0 | sort --version-sort | tail --lines=1)
|
||||||
real_nodejs_version=$(basename $real_nodejs_version)
|
real_nodejs_version=$(basename $real_nodejs_version)
|
||||||
|
|
||||||
# Create a symbolic link for this major version if the file doesn't already exist
|
# Create a symbolic link for this major version if the file doesn't already exist
|
||||||
if [ ! -e "$node_version_path/$nodejs_version" ]
|
if [ ! -e "$node_version_path/$nodejs_version" ]
|
||||||
then
|
then
|
||||||
ln --symbolic --force --no-target-directory $node_version_path/$real_nodejs_version $node_version_path/$nodejs_version
|
ln --symbolic --force --no-target-directory $node_version_path/$real_nodejs_version $node_version_path/$nodejs_version
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Store the ID of this app and the version of node requested for it
|
# Store the ID of this app and the version of node requested for it
|
||||||
echo "$YNH_APP_INSTANCE_NAME:$nodejs_version" | tee --append "$n_install_dir/ynh_app_version"
|
echo "$YNH_APP_INSTANCE_NAME:$nodejs_version" | tee --append "$n_install_dir/ynh_app_version"
|
||||||
|
|
||||||
# Store nodejs_version into the config of this app
|
# Store nodejs_version into the config of this app
|
||||||
ynh_app_setting_set --app=$app --key=nodejs_version --value=$nodejs_version
|
ynh_app_setting_set --app=$app --key=nodejs_version --value=$nodejs_version
|
||||||
|
|
||||||
# Build the update script and set the cronjob
|
# Build the update script and set the cronjob
|
||||||
ynh_cron_upgrade_node
|
ynh_cron_upgrade_node
|
||||||
|
|
||||||
ynh_use_nodejs
|
ynh_use_nodejs
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove the version of node used by the app.
|
# Remove the version of node used by the app.
|
||||||
|
@ -142,25 +144,25 @@ ynh_install_nodejs () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
# Requires YunoHost version 2.7.12 or higher.
|
||||||
ynh_remove_nodejs () {
|
ynh_remove_nodejs () {
|
||||||
nodejs_version=$(ynh_app_setting_get --app=$app --key=nodejs_version)
|
nodejs_version=$(ynh_app_setting_get --app=$app --key=nodejs_version)
|
||||||
|
|
||||||
# Remove the line for this app
|
# Remove the line for this app
|
||||||
sed --in-place "/$YNH_APP_INSTANCE_NAME:$nodejs_version/d" "$n_install_dir/ynh_app_version"
|
sed --in-place "/$YNH_APP_INSTANCE_NAME:$nodejs_version/d" "$n_install_dir/ynh_app_version"
|
||||||
|
|
||||||
# If no other app uses this version of nodejs, remove it.
|
# If no other app uses this version of nodejs, remove it.
|
||||||
if ! grep --quiet "$nodejs_version" "$n_install_dir/ynh_app_version"
|
if ! grep --quiet "$nodejs_version" "$n_install_dir/ynh_app_version"
|
||||||
then
|
then
|
||||||
$n_install_dir/bin/n rm $nodejs_version
|
$n_install_dir/bin/n rm $nodejs_version
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If no other app uses n, remove n
|
# If no other app uses n, remove n
|
||||||
if [ ! -s "$n_install_dir/ynh_app_version" ]
|
if [ ! -s "$n_install_dir/ynh_app_version" ]
|
||||||
then
|
then
|
||||||
ynh_secure_remove --file="$n_install_dir"
|
ynh_secure_remove --file="$n_install_dir"
|
||||||
ynh_secure_remove --file="/usr/local/n"
|
ynh_secure_remove --file="/usr/local/n"
|
||||||
sed --in-place "/N_PREFIX/d" /root/.bashrc
|
sed --in-place "/N_PREFIX/d" /root/.bashrc
|
||||||
rm -f /etc/cron.daily/node_update
|
rm --force /etc/cron.daily/node_update
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set a cron design to update your node versions
|
# Set a cron design to update your node versions
|
||||||
|
@ -173,8 +175,8 @@ ynh_remove_nodejs () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
# Requires YunoHost version 2.7.12 or higher.
|
||||||
ynh_cron_upgrade_node () {
|
ynh_cron_upgrade_node () {
|
||||||
# Build the update script
|
# Build the update script
|
||||||
cat > "$n_install_dir/node_update.sh" << EOF
|
cat > "$n_install_dir/node_update.sh" << EOF
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
version_path="$node_version_path"
|
version_path="$node_version_path"
|
||||||
|
@ -195,26 +197,26 @@ all_real_version=\$(echo "\$all_real_version" | sort --unique)
|
||||||
# Read each major version
|
# Read each major version
|
||||||
while read version
|
while read version
|
||||||
do
|
do
|
||||||
echo "Update of the version \$version"
|
echo "Update of the version \$version"
|
||||||
sudo \$n_install_dir/bin/n \$version
|
sudo \$n_install_dir/bin/n \$version
|
||||||
|
|
||||||
# Find the last "real" version for this major version of node.
|
# Find the last "real" version for this major version of node.
|
||||||
real_nodejs_version=\$(find \$version_path/\$version* -maxdepth 0 | sort --version-sort | tail --lines=1)
|
real_nodejs_version=\$(find \$version_path/\$version* -maxdepth 0 | sort --version-sort | tail --lines=1)
|
||||||
real_nodejs_version=\$(basename \$real_nodejs_version)
|
real_nodejs_version=\$(basename \$real_nodejs_version)
|
||||||
|
|
||||||
# Update the symbolic link for this version
|
# Update the symbolic link for this version
|
||||||
sudo ln --symbolic --force --no-target-directory \$version_path/\$real_nodejs_version \$version_path/\$version
|
sudo ln --symbolic --force --no-target-directory \$version_path/\$real_nodejs_version \$version_path/\$version
|
||||||
done <<< "\$(echo "\$all_real_version")"
|
done <<< "\$(echo "\$all_real_version")"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
chmod +x "$n_install_dir/node_update.sh"
|
chmod +x "$n_install_dir/node_update.sh"
|
||||||
|
|
||||||
# Build the cronjob
|
# Build the cronjob
|
||||||
cat > "/etc/cron.daily/node_update" << EOF
|
cat > "/etc/cron.daily/node_update" << EOF
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
$n_install_dir/node_update.sh >> $n_install_dir/node_update.log
|
$n_install_dir/node_update.sh >> $n_install_dir/node_update.log
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
chmod +x "/etc/cron.daily/node_update"
|
chmod +x "/etc/cron.daily/node_update"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +1,264 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
readonly YNH_DEFAULT_PHP_VERSION=7.0
|
||||||
|
# Declare the actual php version to use.
|
||||||
|
# A packager willing to use another version of php can override the variable into its _common.sh.
|
||||||
|
YNH_PHP_VERSION=${YNH_PHP_VERSION:-$YNH_DEFAULT_PHP_VERSION}
|
||||||
|
|
||||||
# Create a dedicated php-fpm config
|
# Create a dedicated php-fpm config
|
||||||
#
|
#
|
||||||
# usage: ynh_add_fpm_config [--phpversion=7.X]
|
# usage 1: ynh_add_fpm_config [--phpversion=7.X] [--use_template] [--package=packages] [--dedicated_service]
|
||||||
# | arg: -v, --phpversion - Version of php to use.
|
# | arg: -v, --phpversion= - Version of php to use.
|
||||||
|
# | arg: -t, --use_template - Use this helper in template mode.
|
||||||
|
# | arg: -p, --package= - Additionnal php packages to install
|
||||||
|
# | arg: -d, --dedicated_service - Use a dedicated php-fpm service instead of the common one.
|
||||||
|
#
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# usage 2: ynh_add_fpm_config [--phpversion=7.X] --usage=usage --footprint=footprint [--package=packages] [--dedicated_service]
|
||||||
|
# | arg: -v, --phpversion= - Version of php to use.
|
||||||
|
# | arg: -f, --footprint= - Memory footprint of the service (low/medium/high).
|
||||||
|
# low - Less than 20Mb of ram by pool.
|
||||||
|
# medium - Between 20Mb and 40Mb of ram by pool.
|
||||||
|
# high - More than 40Mb of ram by pool.
|
||||||
|
# Or specify exactly the footprint, the load of the service as Mb by pool instead of having a standard value.
|
||||||
|
# To have this value, use the following command and stress the service.
|
||||||
|
# watch -n0.5 ps -o user,cmd,%cpu,rss -u APP
|
||||||
|
#
|
||||||
|
# | arg: -u, --usage= - Expected usage of the service (low/medium/high).
|
||||||
|
# low - Personal usage, behind the sso.
|
||||||
|
# medium - Low usage, few people or/and publicly accessible.
|
||||||
|
# high - High usage, frequently visited website.
|
||||||
|
#
|
||||||
|
# | arg: -p, --package= - Additionnal php packages to install for a specific version of php
|
||||||
|
# | arg: -d, --dedicated_service - Use a dedicated php-fpm service instead of the common one.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The footprint of the service will be used to defined the maximum footprint we can allow, which is half the maximum RAM.
|
||||||
|
# So it will be used to defined 'pm.max_children'
|
||||||
|
# A lower value for the footprint will allow more children for 'pm.max_children'. And so for
|
||||||
|
# 'pm.start_servers', 'pm.min_spare_servers' and 'pm.max_spare_servers' which are defined from the
|
||||||
|
# value of 'pm.max_children'
|
||||||
|
# NOTE: 'pm.max_children' can't exceed 4 times the number of processor's cores.
|
||||||
|
#
|
||||||
|
# The usage value will defined the way php will handle the children for the pool.
|
||||||
|
# A value set as 'low' will set the process manager to 'ondemand'. Children will start only if the
|
||||||
|
# service is used, otherwise no child will stay alive. This config gives the lower footprint when the
|
||||||
|
# service is idle. But will use more proc since it has to start a child as soon it's used.
|
||||||
|
# Set as 'medium', the process manager will be at dynamic. If the service is idle, a number of children
|
||||||
|
# equal to pm.min_spare_servers will stay alive. So the service can be quick to answer to any request.
|
||||||
|
# The number of children can grow if needed. The footprint can stay low if the service is idle, but
|
||||||
|
# not null. The impact on the proc is a little bit less than 'ondemand' as there's always a few
|
||||||
|
# children already available.
|
||||||
|
# Set as 'high', the process manager will be set at 'static'. There will be always as many children as
|
||||||
|
# 'pm.max_children', the footprint is important (but will be set as maximum a quarter of the maximum
|
||||||
|
# RAM) but the impact on the proc is lower. The service will be quick to answer as there's always many
|
||||||
|
# children ready to answer.
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
|
# Requires YunoHost version 3.5.1 or higher for the argument --phpversion
|
||||||
|
# Requires YunoHost version 3.8.1 or higher for the arguments --use_template, --usage, --footprint, --package and --dedicated_service
|
||||||
ynh_add_fpm_config () {
|
ynh_add_fpm_config () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=v
|
local legacy_args=vtufpd
|
||||||
declare -Ar args_array=( [v]=phpversion= )
|
local -A args_array=( [v]=phpversion= [t]=use_template [u]=usage= [f]=footprint= [p]=package= [d]=dedicated_service )
|
||||||
local phpversion
|
local phpversion
|
||||||
# Manage arguments with getopts
|
local use_template
|
||||||
ynh_handle_getopts_args "$@"
|
local usage
|
||||||
|
local footprint
|
||||||
|
local package
|
||||||
|
local dedicated_service
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
package=${package:-}
|
||||||
|
|
||||||
# Configure PHP-FPM 7.0 by default
|
# The default behaviour is to use the template.
|
||||||
phpversion="${phpversion:-7.0}"
|
use_template="${use_template:-1}"
|
||||||
|
usage="${usage:-}"
|
||||||
|
footprint="${footprint:-}"
|
||||||
|
if [ -n "$usage" ] || [ -n "$footprint" ]; then
|
||||||
|
use_template=0
|
||||||
|
fi
|
||||||
|
# Do not use a dedicated service by default
|
||||||
|
dedicated_service=${dedicated_service:-0}
|
||||||
|
|
||||||
local fpm_config_dir="/etc/php/$phpversion/fpm"
|
# Set the default PHP-FPM version by default
|
||||||
local fpm_service="php${phpversion}-fpm"
|
phpversion="${phpversion:-$YNH_PHP_VERSION}"
|
||||||
# Configure PHP-FPM 5 on Debian Jessie
|
|
||||||
if [ "$(ynh_get_debian_release)" == "jessie" ]; then
|
|
||||||
fpm_config_dir="/etc/php5/fpm"
|
|
||||||
fpm_service="php5-fpm"
|
|
||||||
fi
|
|
||||||
ynh_app_setting_set --app=$app --key=fpm_config_dir --value="$fpm_config_dir"
|
|
||||||
ynh_app_setting_set --app=$app --key=fpm_service --value="$fpm_service"
|
|
||||||
finalphpconf="$fpm_config_dir/pool.d/$app.conf"
|
|
||||||
ynh_backup_if_checksum_is_different --file="$finalphpconf"
|
|
||||||
sudo cp ../conf/php-fpm.conf "$finalphpconf"
|
|
||||||
ynh_replace_string --match_string="__NAMETOCHANGE__" --replace_string="$app" --target_file="$finalphpconf"
|
|
||||||
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalphpconf"
|
|
||||||
ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$finalphpconf"
|
|
||||||
ynh_replace_string --match_string="__PHPVERSION__" --replace_string="$phpversion" --target_file="$finalphpconf"
|
|
||||||
sudo chown root: "$finalphpconf"
|
|
||||||
ynh_store_file_checksum --file="$finalphpconf"
|
|
||||||
|
|
||||||
if [ -e "../conf/php-fpm.ini" ]
|
# If the requested php version is not the default version for YunoHost
|
||||||
then
|
if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ]
|
||||||
echo "Packagers ! Please do not use a separate php ini file, merge your directives in the pool file instead." >&2
|
then
|
||||||
finalphpini="$fpm_config_dir/conf.d/20-$app.ini"
|
# If the argument --package is used, add the packages to ynh_install_php to install them from sury
|
||||||
ynh_backup_if_checksum_is_different "$finalphpini"
|
if [ -n "$package" ]
|
||||||
sudo cp ../conf/php-fpm.ini "$finalphpini"
|
then
|
||||||
sudo chown root: "$finalphpini"
|
local additionnal_packages="--package=$package"
|
||||||
ynh_store_file_checksum "$finalphpini"
|
else
|
||||||
fi
|
local additionnal_packages=""
|
||||||
ynh_systemd_action --service_name=$fpm_service --action=reload
|
fi
|
||||||
|
# Install this specific version of php.
|
||||||
|
ynh_install_php --phpversion="$phpversion" "$additionnal_packages"
|
||||||
|
elif [ -n "$package" ]
|
||||||
|
then
|
||||||
|
# Install the additionnal packages from the default repository
|
||||||
|
ynh_add_app_dependencies --package="$package"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $dedicated_service -eq 1 ]
|
||||||
|
then
|
||||||
|
local fpm_service="${app}-phpfpm"
|
||||||
|
local fpm_config_dir="/etc/php/$phpversion/dedicated-fpm"
|
||||||
|
else
|
||||||
|
local fpm_service="php${phpversion}-fpm"
|
||||||
|
local fpm_config_dir="/etc/php/$phpversion/fpm"
|
||||||
|
fi
|
||||||
|
# Configure PHP-FPM 5 on Debian Jessie
|
||||||
|
if [ "$(ynh_get_debian_release)" == "jessie" ]
|
||||||
|
then
|
||||||
|
fpm_config_dir="/etc/php5/fpm"
|
||||||
|
fpm_service="php5-fpm"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the directory for fpm pools
|
||||||
|
mkdir --parents "$fpm_config_dir/pool.d"
|
||||||
|
|
||||||
|
ynh_app_setting_set --app=$app --key=fpm_config_dir --value="$fpm_config_dir"
|
||||||
|
ynh_app_setting_set --app=$app --key=fpm_service --value="$fpm_service"
|
||||||
|
ynh_app_setting_set --app=$app --key=fpm_dedicated_service --value="$dedicated_service"
|
||||||
|
ynh_app_setting_set --app=$app --key=phpversion --value=$phpversion
|
||||||
|
finalphpconf="$fpm_config_dir/pool.d/$app.conf"
|
||||||
|
|
||||||
|
# Migrate from mutual php service to dedicated one.
|
||||||
|
if [ $dedicated_service -eq 1 ]
|
||||||
|
then
|
||||||
|
local old_fpm_config_dir="/etc/php/$phpversion/fpm"
|
||||||
|
# If a config file exist in the common pool, move it.
|
||||||
|
if [ -e "$old_fpm_config_dir/pool.d/$app.conf" ]
|
||||||
|
then
|
||||||
|
ynh_print_info --message="Migrate to a dedicated php-fpm service for $app."
|
||||||
|
# Create a backup of the old file before migration
|
||||||
|
ynh_backup_if_checksum_is_different --file="$old_fpm_config_dir/pool.d/$app.conf"
|
||||||
|
# Remove the old php config file
|
||||||
|
ynh_secure_remove --file="$old_fpm_config_dir/pool.d/$app.conf"
|
||||||
|
# Reload php to release the socket and allow the dedicated service to use it
|
||||||
|
ynh_systemd_action --service_name=php${phpversion}-fpm --action=reload
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
ynh_backup_if_checksum_is_different --file="$finalphpconf"
|
||||||
|
|
||||||
|
if [ $use_template -eq 1 ]
|
||||||
|
then
|
||||||
|
# Usage 1, use the template in ../conf/php-fpm.conf
|
||||||
|
cp ../conf/php-fpm.conf "$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="__NAMETOCHANGE__" --replace_string="$app" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="__PHPVERSION__" --replace_string="$phpversion" --target_file="$finalphpconf"
|
||||||
|
|
||||||
|
else
|
||||||
|
# Usage 2, generate a php-fpm config file with ynh_get_scalable_phpfpm
|
||||||
|
|
||||||
|
# Store settings
|
||||||
|
ynh_app_setting_set --app=$app --key=fpm_footprint --value=$footprint
|
||||||
|
ynh_app_setting_set --app=$app --key=fpm_usage --value=$usage
|
||||||
|
|
||||||
|
# Define the values to use for the configuration of php.
|
||||||
|
ynh_get_scalable_phpfpm --usage=$usage --footprint=$footprint
|
||||||
|
|
||||||
|
# Copy the default file
|
||||||
|
cp "/etc/php/$phpversion/fpm/pool.d/www.conf" "$finalphpconf"
|
||||||
|
|
||||||
|
# Replace standard variables into the default file
|
||||||
|
ynh_replace_string --match_string="^\[www\]" --replace_string="[$app]" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string=".*listen = .*" --replace_string="listen = /var/run/php/php$phpversion-fpm-$app.sock" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="^user = .*" --replace_string="user = $app" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="^group = .*" --replace_string="group = $app" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string=".*chdir = .*" --replace_string="chdir = $final_path" --target_file="$finalphpconf"
|
||||||
|
|
||||||
|
# Configure fpm children
|
||||||
|
ynh_replace_string --match_string=".*pm = .*" --replace_string="pm = $php_pm" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string=".*pm.max_children = .*" --replace_string="pm.max_children = $php_max_children" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string=".*pm.max_requests = .*" --replace_string="pm.max_requests = 500" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string=".*request_terminate_timeout = .*" --replace_string="request_terminate_timeout = 1d" --target_file="$finalphpconf"
|
||||||
|
if [ "$php_pm" = "dynamic" ]
|
||||||
|
then
|
||||||
|
ynh_replace_string --match_string=".*pm.start_servers = .*" --replace_string="pm.start_servers = $php_start_servers" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string=".*pm.min_spare_servers = .*" --replace_string="pm.min_spare_servers = $php_min_spare_servers" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string=".*pm.max_spare_servers = .*" --replace_string="pm.max_spare_servers = $php_max_spare_servers" --target_file="$finalphpconf"
|
||||||
|
elif [ "$php_pm" = "ondemand" ]
|
||||||
|
then
|
||||||
|
ynh_replace_string --match_string=".*pm.process_idle_timeout = .*" --replace_string="pm.process_idle_timeout = 10s" --target_file="$finalphpconf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Comment unused parameters
|
||||||
|
if [ "$php_pm" != "dynamic" ]
|
||||||
|
then
|
||||||
|
ynh_replace_string --match_string=".*\(pm.start_servers = .*\)" --replace_string=";\1" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string=".*\(pm.min_spare_servers = .*\)" --replace_string=";\1" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string=".*\(pm.max_spare_servers = .*\)" --replace_string=";\1" --target_file="$finalphpconf"
|
||||||
|
fi
|
||||||
|
if [ "$php_pm" != "ondemand" ]
|
||||||
|
then
|
||||||
|
ynh_replace_string --match_string=".*\(pm.process_idle_timeout = .*\)" --replace_string=";\1" --target_file="$finalphpconf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Concatene the extra config.
|
||||||
|
if [ -e ../conf/extra_php-fpm.conf ]; then
|
||||||
|
cat ../conf/extra_php-fpm.conf >> "$finalphpconf"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
chown root: "$finalphpconf"
|
||||||
|
ynh_store_file_checksum --file="$finalphpconf"
|
||||||
|
|
||||||
|
if [ -e "../conf/php-fpm.ini" ]
|
||||||
|
then
|
||||||
|
ynh_print_warn -message="Packagers ! Please do not use a separate php ini file, merge your directives in the pool file instead."
|
||||||
|
finalphpini="$fpm_config_dir/conf.d/20-$app.ini"
|
||||||
|
ynh_backup_if_checksum_is_different "$finalphpini"
|
||||||
|
cp ../conf/php-fpm.ini "$finalphpini"
|
||||||
|
chown root: "$finalphpini"
|
||||||
|
ynh_store_file_checksum "$finalphpini"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $dedicated_service -eq 1 ]
|
||||||
|
then
|
||||||
|
# Create a dedicated php-fpm.conf for the service
|
||||||
|
local globalphpconf=$fpm_config_dir/php-fpm-$app.conf
|
||||||
|
cp /etc/php/${phpversion}/fpm/php-fpm.conf $globalphpconf
|
||||||
|
|
||||||
|
ynh_replace_string --match_string="^[; ]*pid *=.*" --replace_string="pid = /run/php/php${phpversion}-fpm-$app.pid" --target_file="$globalphpconf"
|
||||||
|
ynh_replace_string --match_string="^[; ]*error_log *=.*" --replace_string="error_log = /var/log/php/fpm-php.$app.log" --target_file="$globalphpconf"
|
||||||
|
ynh_replace_string --match_string="^[; ]*syslog.ident *=.*" --replace_string="syslog.ident = php-fpm-$app" --target_file="$globalphpconf"
|
||||||
|
ynh_replace_string --match_string="^[; ]*include *=.*" --replace_string="include = $finalphpconf" --target_file="$globalphpconf"
|
||||||
|
|
||||||
|
# Create a config for a dedicated php-fpm service for the app
|
||||||
|
echo "[Unit]
|
||||||
|
Description=PHP $phpversion FastCGI Process Manager for $app
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
PIDFile=/run/php/php${phpversion}-fpm-$app.pid
|
||||||
|
ExecStart=/usr/sbin/php-fpm$phpversion --nodaemonize --fpm-config $globalphpconf
|
||||||
|
ExecReload=/bin/kill -USR2 \$MAINPID
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
" > ../conf/$fpm_service
|
||||||
|
|
||||||
|
# Create this dedicated php-fpm service
|
||||||
|
ynh_add_systemd_config --service=$fpm_service --template=$fpm_service
|
||||||
|
# Integrate the service in YunoHost admin panel
|
||||||
|
yunohost service add $fpm_service --log /var/log/php/fpm-php.$app.log --log_type file --description "Php-fpm dedicated to $app"
|
||||||
|
# Configure log rotate
|
||||||
|
ynh_use_logrotate --logfile=/var/log/php
|
||||||
|
# Restart the service, as this service is either stopped or only for this app
|
||||||
|
ynh_systemd_action --service_name=$fpm_service --action=restart
|
||||||
|
else
|
||||||
|
# Reload php, to not impact other parts of the system using php
|
||||||
|
ynh_systemd_action --service_name=$fpm_service --action=reload
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove the dedicated php-fpm config
|
# Remove the dedicated php-fpm config
|
||||||
|
@ -54,14 +267,291 @@ ynh_add_fpm_config () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
ynh_remove_fpm_config () {
|
ynh_remove_fpm_config () {
|
||||||
local fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir)
|
local fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir)
|
||||||
local fpm_service=$(ynh_app_setting_get --app=$app --key=fpm_service)
|
local fpm_service=$(ynh_app_setting_get --app=$app --key=fpm_service)
|
||||||
# Assume php version 7 if not set
|
local dedicated_service=$(ynh_app_setting_get --app=$app --key=fpm_dedicated_service)
|
||||||
if [ -z "$fpm_config_dir" ]; then
|
dedicated_service=${dedicated_service:-0}
|
||||||
fpm_config_dir="/etc/php/7.0/fpm"
|
# Get the version of php used by this app
|
||||||
fpm_service="php7.0-fpm"
|
local phpversion=$(ynh_app_setting_get $app phpversion)
|
||||||
fi
|
|
||||||
ynh_secure_remove --file="$fpm_config_dir/pool.d/$app.conf"
|
# Assume default PHP-FPM version by default
|
||||||
ynh_secure_remove --file="$fpm_config_dir/conf.d/20-$app.ini" 2>&1
|
phpversion="${phpversion:-$YNH_DEFAULT_PHP_VERSION}"
|
||||||
ynh_systemd_action --service_name=$fpm_service --action=reload
|
|
||||||
|
# Assume default php files if not set
|
||||||
|
if [ -z "$fpm_config_dir" ]
|
||||||
|
then
|
||||||
|
fpm_config_dir="/etc/php/$YNH_DEFAULT_PHP_VERSION/fpm"
|
||||||
|
fpm_service="php$YNH_DEFAULT_PHP_VERSION-fpm"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $dedicated_service -eq 1 ]
|
||||||
|
then
|
||||||
|
# Remove the dedicated service php-fpm service for the app
|
||||||
|
ynh_remove_systemd_config --service=$fpm_service
|
||||||
|
# Remove the global php-fpm conf
|
||||||
|
ynh_secure_remove --file="$fpm_config_dir/php-fpm-$app.conf"
|
||||||
|
# Remove the service from the list of services known by Yunohost
|
||||||
|
yunohost service remove $fpm_service
|
||||||
|
elif ynh_package_is_installed --package="php${phpversion}-fpm"; then
|
||||||
|
ynh_systemd_action --service_name=$fpm_service --action=reload
|
||||||
|
fi
|
||||||
|
|
||||||
|
ynh_secure_remove --file="$fpm_config_dir/pool.d/$app.conf"
|
||||||
|
ynh_exec_warn_less ynh_secure_remove --file="$fpm_config_dir/conf.d/20-$app.ini"
|
||||||
|
|
||||||
|
# If the php version used is not the default version for YunoHost
|
||||||
|
if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ]
|
||||||
|
then
|
||||||
|
# Remove this specific version of php
|
||||||
|
ynh_remove_php
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install another version of php.
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# usage: ynh_install_php --phpversion=phpversion [--package=packages]
|
||||||
|
# | arg: -v, --phpversion= - Version of php to install.
|
||||||
|
# | arg: -p, --package= - Additionnal php packages to install
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_install_php () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=vp
|
||||||
|
local -A args_array=( [v]=phpversion= [p]=package= )
|
||||||
|
local phpversion
|
||||||
|
local package
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
package=${package:-}
|
||||||
|
|
||||||
|
# Store phpversion into the config of this app
|
||||||
|
ynh_app_setting_set $app phpversion $phpversion
|
||||||
|
|
||||||
|
if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ]
|
||||||
|
then
|
||||||
|
ynh_die "Do not use ynh_install_php to install php$YNH_DEFAULT_PHP_VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the file if doesn't exist already
|
||||||
|
touch /etc/php/ynh_app_version
|
||||||
|
|
||||||
|
# Do not add twice the same line
|
||||||
|
if ! grep --quiet "$YNH_APP_INSTANCE_NAME:" "/etc/php/ynh_app_version"
|
||||||
|
then
|
||||||
|
# Store the ID of this app and the version of php requested for it
|
||||||
|
echo "$YNH_APP_INSTANCE_NAME:$phpversion" | tee --append "/etc/php/ynh_app_version"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add an extra repository for those packages
|
||||||
|
ynh_install_extra_repo --repo="https://packages.sury.org/php/ $(ynh_get_debian_release) main" --key="https://packages.sury.org/php/apt.gpg" --priority=995 --name=extra_php_version
|
||||||
|
|
||||||
|
# Install requested dependencies from this extra repository.
|
||||||
|
# Install php-fpm first, otherwise php will install apache as a dependency.
|
||||||
|
ynh_add_app_dependencies --package="php${phpversion}-fpm"
|
||||||
|
ynh_add_app_dependencies --package="php$phpversion php${phpversion}-common $package"
|
||||||
|
|
||||||
|
# Set the default php version back as the default version for php-cli.
|
||||||
|
update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
||||||
|
|
||||||
|
# Pin this extra repository after packages are installed to prevent sury of doing shit
|
||||||
|
ynh_pin_repo --package="*" --pin="origin \"packages.sury.org\"" --priority=200 --name=extra_php_version
|
||||||
|
ynh_pin_repo --package="php${YNH_DEFAULT_PHP_VERSION}*" --pin="origin \"packages.sury.org\"" --priority=600 --name=extra_php_version --append
|
||||||
|
|
||||||
|
# Advertise service in admin panel
|
||||||
|
yunohost service add php${phpversion}-fpm --log "/var/log/php${phpversion}-fpm.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the specific version of php used by the app.
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# usage: ynh_install_php
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
|
ynh_remove_php () {
|
||||||
|
# Get the version of php used by this app
|
||||||
|
local phpversion=$(ynh_app_setting_get $app phpversion)
|
||||||
|
|
||||||
|
if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ] || [ -z "$phpversion" ]
|
||||||
|
then
|
||||||
|
if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ]
|
||||||
|
then
|
||||||
|
ynh_print_err "Do not use ynh_remove_php to remove php$YNH_DEFAULT_PHP_VERSION !"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the file if doesn't exist already
|
||||||
|
touch /etc/php/ynh_app_version
|
||||||
|
|
||||||
|
# Remove the line for this app
|
||||||
|
sed --in-place "/$YNH_APP_INSTANCE_NAME:$phpversion/d" "/etc/php/ynh_app_version"
|
||||||
|
|
||||||
|
# If no other app uses this version of php, remove it.
|
||||||
|
if ! grep --quiet "$phpversion" "/etc/php/ynh_app_version"
|
||||||
|
then
|
||||||
|
# Remove the service from the admin panel
|
||||||
|
if ynh_package_is_installed --package="php${phpversion}-fpm"; then
|
||||||
|
yunohost service remove php${phpversion}-fpm
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Purge php dependencies for this version.
|
||||||
|
ynh_package_autopurge "php$phpversion php${phpversion}-fpm php${phpversion}-common"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define the values to configure php-fpm
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# usage: ynh_get_scalable_phpfpm --usage=usage --footprint=footprint [--print]
|
||||||
|
# | arg: -f, --footprint= - Memory footprint of the service (low/medium/high).
|
||||||
|
# low - Less than 20Mb of ram by pool.
|
||||||
|
# medium - Between 20Mb and 40Mb of ram by pool.
|
||||||
|
# high - More than 40Mb of ram by pool.
|
||||||
|
# Or specify exactly the footprint, the load of the service as Mb by pool instead of having a standard value.
|
||||||
|
# To have this value, use the following command and stress the service.
|
||||||
|
# watch -n0.5 ps -o user,cmd,%cpu,rss -u APP
|
||||||
|
#
|
||||||
|
# | arg: -u, --usage= - Expected usage of the service (low/medium/high).
|
||||||
|
# low - Personal usage, behind the sso.
|
||||||
|
# medium - Low usage, few people or/and publicly accessible.
|
||||||
|
# high - High usage, frequently visited website.
|
||||||
|
#
|
||||||
|
# | arg: -p, --print - Print the result (intended for debug purpose only when packaging the app)
|
||||||
|
ynh_get_scalable_phpfpm () {
|
||||||
|
local legacy_args=ufp
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local -A args_array=( [u]=usage= [f]=footprint= [p]=print )
|
||||||
|
local usage
|
||||||
|
local footprint
|
||||||
|
local print
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
# Set all characters as lowercase
|
||||||
|
footprint=${footprint,,}
|
||||||
|
usage=${usage,,}
|
||||||
|
print=${print:-0}
|
||||||
|
|
||||||
|
if [ "$footprint" = "low" ]
|
||||||
|
then
|
||||||
|
footprint=20
|
||||||
|
elif [ "$footprint" = "medium" ]
|
||||||
|
then
|
||||||
|
footprint=35
|
||||||
|
elif [ "$footprint" = "high" ]
|
||||||
|
then
|
||||||
|
footprint=50
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Define the factor to determine min_spare_servers
|
||||||
|
# to avoid having too few children ready to start for heavy apps
|
||||||
|
if [ $footprint -le 20 ]
|
||||||
|
then
|
||||||
|
min_spare_servers_factor=8
|
||||||
|
elif [ $footprint -le 35 ]
|
||||||
|
then
|
||||||
|
min_spare_servers_factor=5
|
||||||
|
else
|
||||||
|
min_spare_servers_factor=3
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Define the way the process manager handle child processes.
|
||||||
|
if [ "$usage" = "low" ]
|
||||||
|
then
|
||||||
|
php_pm=ondemand
|
||||||
|
elif [ "$usage" = "medium" ]
|
||||||
|
then
|
||||||
|
php_pm=dynamic
|
||||||
|
elif [ "$usage" = "high" ]
|
||||||
|
then
|
||||||
|
php_pm=static
|
||||||
|
else
|
||||||
|
ynh_die --message="Does not recognize '$usage' as an usage value."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the total of RAM available, except swap.
|
||||||
|
local max_ram=$(ynh_get_ram --total --ignore_swap)
|
||||||
|
|
||||||
|
at_least_one() {
|
||||||
|
# Do not allow value below 1
|
||||||
|
if [ $1 -le 0 ]
|
||||||
|
then
|
||||||
|
echo 1
|
||||||
|
else
|
||||||
|
echo $1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define pm.max_children
|
||||||
|
# The value of pm.max_children is the total amount of ram divide by 2 and divide again by the footprint of a pool for this app.
|
||||||
|
# So if php-fpm start the maximum of children, it won't exceed half of the ram.
|
||||||
|
php_max_children=$(( $max_ram / 2 / $footprint ))
|
||||||
|
# If process manager is set as static, use half less children.
|
||||||
|
# Used as static, there's always as many children as the value of pm.max_children
|
||||||
|
if [ "$php_pm" = "static" ]
|
||||||
|
then
|
||||||
|
php_max_children=$(( $php_max_children / 2 ))
|
||||||
|
fi
|
||||||
|
php_max_children=$(at_least_one $php_max_children)
|
||||||
|
|
||||||
|
# To not overload the proc, limit the number of children to 4 times the number of cores.
|
||||||
|
local core_number=$(nproc)
|
||||||
|
local max_proc=$(( $core_number * 4 ))
|
||||||
|
if [ $php_max_children -gt $max_proc ]
|
||||||
|
then
|
||||||
|
php_max_children=$max_proc
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get a potential forced value for php_max_children
|
||||||
|
local php_forced_max_children=$(ynh_app_setting_get --app=$app --key=php_forced_max_children)
|
||||||
|
if [ -n "$php_forced_max_children" ]; then
|
||||||
|
php_max_children=$php_forced_max_children
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$php_pm" = "dynamic" ]
|
||||||
|
then
|
||||||
|
# Define pm.start_servers, pm.min_spare_servers and pm.max_spare_servers for a dynamic process manager
|
||||||
|
php_min_spare_servers=$(( $php_max_children / $min_spare_servers_factor ))
|
||||||
|
php_min_spare_servers=$(at_least_one $php_min_spare_servers)
|
||||||
|
|
||||||
|
php_max_spare_servers=$(( $php_max_children / 2 ))
|
||||||
|
php_max_spare_servers=$(at_least_one $php_max_spare_servers)
|
||||||
|
|
||||||
|
php_start_servers=$(( $php_min_spare_servers + ( $php_max_spare_servers - $php_min_spare_servers ) /2 ))
|
||||||
|
php_start_servers=$(at_least_one $php_start_servers)
|
||||||
|
else
|
||||||
|
php_min_spare_servers=0
|
||||||
|
php_max_spare_servers=0
|
||||||
|
php_start_servers=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $print -eq 1 ]
|
||||||
|
then
|
||||||
|
ynh_debug --message="Footprint=${footprint}Mb by pool."
|
||||||
|
ynh_debug --message="Process manager=$php_pm"
|
||||||
|
ynh_debug --message="Max RAM=${max_ram}Mb"
|
||||||
|
if [ "$php_pm" != "static" ]
|
||||||
|
then
|
||||||
|
ynh_debug --message="\nMax estimated footprint=$(( $php_max_children * $footprint ))"
|
||||||
|
ynh_debug --message="Min estimated footprint=$(( $php_min_spare_servers * $footprint ))"
|
||||||
|
fi
|
||||||
|
if [ "$php_pm" = "dynamic" ]
|
||||||
|
then
|
||||||
|
ynh_debug --message="Estimated average footprint=$(( $php_max_spare_servers * $footprint ))"
|
||||||
|
elif [ "$php_pm" = "static" ]
|
||||||
|
then
|
||||||
|
ynh_debug --message="Estimated footprint=$(( $php_max_children * $footprint ))"
|
||||||
|
fi
|
||||||
|
ynh_debug --message="\nRaw php-fpm values:"
|
||||||
|
ynh_debug --message="pm.max_children = $php_max_children"
|
||||||
|
if [ "$php_pm" = "dynamic" ]
|
||||||
|
then
|
||||||
|
ynh_debug --message="pm.start_servers = $php_start_servers"
|
||||||
|
ynh_debug --message="pm.min_spare_servers = $php_min_spare_servers"
|
||||||
|
ynh_debug --message="pm.max_spare_servers = $php_max_spare_servers"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,65 +9,65 @@ PSQL_ROOT_PWD_FILE=/etc/yunohost/psql
|
||||||
# ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql
|
# ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_connect_as --user=user --password=password [--database=database]
|
# usage: ynh_psql_connect_as --user=user --password=password [--database=database]
|
||||||
# | arg: -u, --user - the user name to connect as
|
# | arg: -u, --user= - the user name to connect as
|
||||||
# | arg: -p, --password - the user password
|
# | arg: -p, --password= - the user password
|
||||||
# | arg: -d, --database - the database to connect to
|
# | arg: -d, --database= - the database to connect to
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_connect_as() {
|
ynh_psql_connect_as() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=upd
|
local legacy_args=upd
|
||||||
declare -Ar args_array=([u]=user= [p]=password= [d]=database=)
|
local -A args_array=([u]=user= [p]=password= [d]=database=)
|
||||||
local user
|
local user
|
||||||
local password
|
local password
|
||||||
local database
|
local database
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
database="${database:-}"
|
database="${database:-}"
|
||||||
|
|
||||||
sudo --login --user=postgres PGUSER="$user" PGPASSWORD="$password" psql "$database"
|
sudo --login --user=postgres PGUSER="$user" PGPASSWORD="$password" psql "$database"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command as root user
|
# Execute a command as root user
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_execute_as_root --sql=sql [--database=database]
|
# usage: ynh_psql_execute_as_root --sql=sql [--database=database]
|
||||||
# | arg: -s, --sql - the SQL command to execute
|
# | arg: -s, --sql= - the SQL command to execute
|
||||||
# | arg: -d, --database - the database to connect to
|
# | arg: -d, --database= - the database to connect to
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_execute_as_root() {
|
ynh_psql_execute_as_root() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=sd
|
local legacy_args=sd
|
||||||
declare -Ar args_array=([s]=sql= [d]=database=)
|
local -A args_array=([s]=sql= [d]=database=)
|
||||||
local sql
|
local sql
|
||||||
local database
|
local database
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
database="${database:-}"
|
database="${database:-}"
|
||||||
|
|
||||||
ynh_psql_connect_as --user="postgres" --password="$(sudo cat $PSQL_ROOT_PWD_FILE)" \
|
ynh_psql_connect_as --user="postgres" --password="$(cat $PSQL_ROOT_PWD_FILE)" \
|
||||||
--database="$database" <<<"$sql"
|
--database="$database" <<<"$sql"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command from a file as root user
|
# Execute a command from a file as root user
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_execute_file_as_root --file=file [--database=database]
|
# usage: ynh_psql_execute_file_as_root --file=file [--database=database]
|
||||||
# | arg: -f, --file - the file containing SQL commands
|
# | arg: -f, --file= - the file containing SQL commands
|
||||||
# | arg: -d, --database - the database to connect to
|
# | arg: -d, --database= - the database to connect to
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_execute_file_as_root() {
|
ynh_psql_execute_file_as_root() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=fd
|
local legacy_args=fd
|
||||||
declare -Ar args_array=([f]=file= [d]=database=)
|
local -A args_array=([f]=file= [d]=database=)
|
||||||
local file
|
local file
|
||||||
local database
|
local database
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
database="${database:-}"
|
database="${database:-}"
|
||||||
|
|
||||||
ynh_psql_connect_as --user="postgres" --password="$(sudo cat $PSQL_ROOT_PWD_FILE)" \
|
ynh_psql_connect_as --user="postgres" --password="$(cat $PSQL_ROOT_PWD_FILE)" \
|
||||||
--database="$database" <"$file"
|
--database="$database" <"$file"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a database and grant optionnaly privilegies to a user
|
# Create a database and grant optionnaly privilegies to a user
|
||||||
|
@ -80,17 +80,18 @@ ynh_psql_execute_file_as_root() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_create_db() {
|
ynh_psql_create_db() {
|
||||||
local db=$1
|
local db=$1
|
||||||
local user=${2:-}
|
local user=${2:-}
|
||||||
|
|
||||||
local sql="CREATE DATABASE ${db};"
|
local sql="CREATE DATABASE ${db};"
|
||||||
|
|
||||||
# grant all privilegies to user
|
# grant all privilegies to user
|
||||||
if [ -n "$user" ]; then
|
if [ -n "$user" ]; then
|
||||||
sql+="GRANT ALL PRIVILEGES ON DATABASE ${db} TO ${user} WITH GRANT OPTION;"
|
sql+="ALTER DATABASE ${db} OWNER TO ${user};"
|
||||||
fi
|
sql+="GRANT ALL PRIVILEGES ON DATABASE ${db} TO ${user} WITH GRANT OPTION;"
|
||||||
|
fi
|
||||||
|
|
||||||
ynh_psql_execute_as_root --sql="$sql"
|
ynh_psql_execute_as_root --sql="$sql"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Drop a database
|
# Drop a database
|
||||||
|
@ -105,12 +106,12 @@ ynh_psql_create_db() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_drop_db() {
|
ynh_psql_drop_db() {
|
||||||
local db=$1
|
local db=$1
|
||||||
# First, force disconnection of all clients connected to the database
|
# First, force disconnection of all clients connected to the database
|
||||||
# https://stackoverflow.com/questions/5408156/how-to-drop-a-postgresql-database-if-there-are-active-connections-to-it
|
# https://stackoverflow.com/questions/17449420/postgresql-unable-to-drop-database-because-of-some-auto-connections-to-db
|
||||||
# https://dba.stackexchange.com/questions/16426/how-to-drop-all-connections-to-a-specific-database-without-stopping-the-server
|
ynh_psql_execute_as_root --sql="REVOKE CONNECT ON DATABASE $db FROM public;" --database="$db"
|
||||||
ynh_psql_execute_as_root --sql="SELECT pg_terminate_backend (pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '$db';" --database="$db"
|
ynh_psql_execute_as_root --sql="SELECT pg_terminate_backend (pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '$db' AND pid <> pg_backend_pid();" --database="$db"
|
||||||
sudo --login --user=postgres dropdb $db
|
sudo --login --user=postgres dropdb $db
|
||||||
}
|
}
|
||||||
|
|
||||||
# Dump a database
|
# Dump a database
|
||||||
|
@ -118,19 +119,19 @@ ynh_psql_drop_db() {
|
||||||
# example: ynh_psql_dump_db 'roundcube' > ./dump.sql
|
# example: ynh_psql_dump_db 'roundcube' > ./dump.sql
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_dump_db --database=database
|
# usage: ynh_psql_dump_db --database=database
|
||||||
# | arg: -d, --database - the database name to dump
|
# | arg: -d, --database= - the database name to dump
|
||||||
# | ret: the psqldump output
|
# | ret: the psqldump output
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_dump_db() {
|
ynh_psql_dump_db() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=d
|
local legacy_args=d
|
||||||
declare -Ar args_array=([d]=database=)
|
local -A args_array=([d]=database=)
|
||||||
local database
|
local database
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
sudo --login --user=postgres pg_dump "$database"
|
sudo --login --user=postgres pg_dump "$database"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a user
|
# Create a user
|
||||||
|
@ -143,47 +144,55 @@ ynh_psql_dump_db() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_create_user() {
|
ynh_psql_create_user() {
|
||||||
local user=$1
|
local user=$1
|
||||||
local pwd=$2
|
local pwd=$2
|
||||||
ynh_psql_execute_as_root --sql="CREATE USER $user WITH ENCRYPTED PASSWORD '$pwd'"
|
ynh_psql_execute_as_root --sql="CREATE USER $user WITH ENCRYPTED PASSWORD '$pwd'"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if a psql user exists
|
# Check if a psql user exists
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_user_exists --user=user
|
# usage: ynh_psql_user_exists --user=user
|
||||||
# | arg: -u, --user - the user for which to check existence
|
# | arg: -u, --user= - the user for which to check existence
|
||||||
|
# | exit: Return 1 if the user doesn't exist, 0 otherwise
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_user_exists() {
|
ynh_psql_user_exists() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=u
|
local legacy_args=u
|
||||||
declare -Ar args_array=([u]=user=)
|
local -A args_array=([u]=user=)
|
||||||
local user
|
local user
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(sudo cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT rolname FROM pg_roles WHERE rolname='$user';" | grep --quiet "$user" ; then
|
if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT rolname FROM pg_roles WHERE rolname='$user';" | grep --quiet "$user"
|
||||||
return 1
|
then
|
||||||
else
|
return 1
|
||||||
return 0
|
else
|
||||||
fi
|
return 0
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if a psql database exists
|
# Check if a psql database exists
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_database_exists --database=database
|
# usage: ynh_psql_database_exists --database=database
|
||||||
# | arg: -d, --database - the database for which to check existence
|
# | arg: -d, --database= - the database for which to check existence
|
||||||
|
# | exit: Return 1 if the database doesn't exist, 0 otherwise
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_database_exists() {
|
ynh_psql_database_exists() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=d
|
local legacy_args=d
|
||||||
declare -Ar args_array=([d]=database=)
|
local -A args_array=([d]=database=)
|
||||||
local database
|
local database
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(sudo cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT datname FROM pg_database WHERE datname='$database';" | grep --quiet "$database"; then
|
if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT datname FROM pg_database WHERE datname='$database';" | grep --quiet "$database"
|
||||||
return 1
|
then
|
||||||
else
|
return 1
|
||||||
return 0
|
else
|
||||||
fi
|
return 0
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Drop a user
|
# Drop a user
|
||||||
|
@ -195,110 +204,121 @@ ynh_psql_database_exists() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_psql_drop_user() {
|
ynh_psql_drop_user() {
|
||||||
ynh_psql_execute_as_root --sql="DROP USER ${1};"
|
ynh_psql_execute_as_root --sql="DROP USER ${1};"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a database, an user and its password. Then store the password in the app's config
|
# Create a database, an user and its password. Then store the password in the app's config
|
||||||
#
|
#
|
||||||
|
# usage: ynh_psql_setup_db --db_user=user --db_name=name [--db_pwd=pwd]
|
||||||
|
# | arg: -u, --db_user= - Owner of the database
|
||||||
|
# | arg: -n, --db_name= - Name of the database
|
||||||
|
# | arg: -p, --db_pwd= - Password of the database. If not given, a password will be generated
|
||||||
|
#
|
||||||
# After executing this helper, the password of the created database will be available in $db_pwd
|
# After executing this helper, the password of the created database will be available in $db_pwd
|
||||||
# It will also be stored as "psqlpwd" into the app settings.
|
# It will also be stored as "psqlpwd" into the app settings.
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_setup_db --db_user=user --db_name=name [--db_pwd=pwd]
|
# Requires YunoHost version 2.7.13 or higher.
|
||||||
# | arg: -u, --db_user - Owner of the database
|
|
||||||
# | arg: -n, --db_name - Name of the database
|
|
||||||
# | arg: -p, --db_pwd - Password of the database. If not given, a password will be generated
|
|
||||||
ynh_psql_setup_db() {
|
ynh_psql_setup_db() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=unp
|
local legacy_args=unp
|
||||||
declare -Ar args_array=([u]=db_user= [n]=db_name= [p]=db_pwd=)
|
local -A args_array=([u]=db_user= [n]=db_name= [p]=db_pwd=)
|
||||||
local db_user
|
local db_user
|
||||||
local db_name
|
local db_name
|
||||||
db_pwd=""
|
db_pwd=""
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
local new_db_pwd=$(ynh_string_random) # Generate a random password
|
local new_db_pwd=$(ynh_string_random) # Generate a random password
|
||||||
# If $db_pwd is not given, use new_db_pwd instead for db_pwd
|
# If $db_pwd is not given, use new_db_pwd instead for db_pwd
|
||||||
db_pwd="${db_pwd:-$new_db_pwd}"
|
db_pwd="${db_pwd:-$new_db_pwd}"
|
||||||
|
|
||||||
if ! ynh_psql_user_exists --user=$db_user; then
|
if ! ynh_psql_user_exists --user=$db_user; then
|
||||||
ynh_psql_create_user "$db_user" "$db_pwd"
|
ynh_psql_create_user "$db_user" "$db_pwd"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ynh_psql_create_db "$db_name" "$db_user" # Create the database
|
ynh_psql_create_db "$db_name" "$db_user" # Create the database
|
||||||
ynh_app_setting_set --app=$app --key=psqlpwd --value=$db_pwd # Store the password in the app's config
|
ynh_app_setting_set --app=$app --key=psqlpwd --value=$db_pwd # Store the password in the app's config
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove a database if it exists, and the associated user
|
# Remove a database if it exists, and the associated user
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_remove_db --db_user=user --db_name=name
|
# usage: ynh_psql_remove_db --db_user=user --db_name=name
|
||||||
# | arg: -u, --db_user - Owner of the database
|
# | arg: -u, --db_user= - Owner of the database
|
||||||
# | arg: -n, --db_name - Name of the database
|
# | arg: -n, --db_name= - Name of the database
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.13 or higher.
|
||||||
ynh_psql_remove_db() {
|
ynh_psql_remove_db() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=un
|
local legacy_args=un
|
||||||
declare -Ar args_array=([u]=db_user= [n]=db_name=)
|
local -A args_array=([u]=db_user= [n]=db_name=)
|
||||||
local db_user
|
local db_user
|
||||||
local db_name
|
local db_name
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
local psql_root_password=$(sudo cat $PSQL_ROOT_PWD_FILE)
|
if ynh_psql_database_exists --database=$db_name
|
||||||
if ynh_psql_database_exists --database=$db_name; then # Check if the database exists
|
then # Check if the database exists
|
||||||
ynh_psql_drop_db $db_name # Remove the database
|
ynh_psql_drop_db $db_name # Remove the database
|
||||||
else
|
else
|
||||||
ynh_print_warn --message="Database $db_name not found"
|
ynh_print_warn --message="Database $db_name not found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Remove psql user if it exists
|
# Remove psql user if it exists
|
||||||
if ynh_psql_user_exists --user=$db_user; then
|
if ynh_psql_user_exists --user=$db_user
|
||||||
ynh_psql_drop_user $db_user
|
then
|
||||||
else
|
ynh_psql_drop_user $db_user
|
||||||
ynh_print_warn --message="User $db_user not found"
|
else
|
||||||
fi
|
ynh_print_warn --message="User $db_user not found"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a master password and set up global settings
|
# Create a master password and set up global settings
|
||||||
# Please always call this script in install and restore scripts
|
# Please always call this script in install and restore scripts
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_test_if_first_run
|
# usage: ynh_psql_test_if_first_run
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.13 or higher.
|
||||||
ynh_psql_test_if_first_run() {
|
ynh_psql_test_if_first_run() {
|
||||||
if [ -f "$PSQL_ROOT_PWD_FILE" ]; then
|
|
||||||
echo "PostgreSQL is already installed, no need to create master password"
|
|
||||||
else
|
|
||||||
local psql_root_password="$(ynh_string_random)"
|
|
||||||
echo "$psql_root_password" >$PSQL_ROOT_PWD_FILE
|
|
||||||
|
|
||||||
if [ -e /etc/postgresql/9.4/ ]; then
|
if [ -f "$PSQL_ROOT_PWD_FILE" ]
|
||||||
local pg_hba=/etc/postgresql/9.4/main/pg_hba.conf
|
then
|
||||||
local logfile=/var/log/postgresql/postgresql-9.4-main.log
|
ynh_print_info --message="PostgreSQL is already installed, no need to create master password"
|
||||||
elif [ -e /etc/postgresql/9.6/ ]; then
|
return
|
||||||
local pg_hba=/etc/postgresql/9.6/main/pg_hba.conf
|
fi
|
||||||
local logfile=/var/log/postgresql/postgresql-9.6-main.log
|
|
||||||
else
|
|
||||||
if dpkg --list | grep -q "ii postgresql-9."
|
|
||||||
then
|
|
||||||
ynh_die "It looks like postgresql was not properly configured ? /etc/postgresql/9.* is missing ... Could be due to a locale issue, c.f.https://serverfault.com/questions/426989/postgresql-etc-postgresql-doesnt-exist"
|
|
||||||
else
|
|
||||||
ynh_die "postgresql shoud be 9.4 or 9.6 or "
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_systemd_action --service_name=postgresql --action=start
|
local psql_root_password="$(ynh_string_random)"
|
||||||
|
echo "$psql_root_password" >$PSQL_ROOT_PWD_FILE
|
||||||
|
|
||||||
sudo --login --user=postgres psql -c"ALTER user postgres WITH PASSWORD '$psql_root_password'" postgres
|
if [ -e /etc/postgresql/9.4/ ]
|
||||||
|
then
|
||||||
|
local pg_hba=/etc/postgresql/9.4/main/pg_hba.conf
|
||||||
|
local logfile=/var/log/postgresql/postgresql-9.4-main.log
|
||||||
|
elif [ -e /etc/postgresql/9.6/ ]
|
||||||
|
then
|
||||||
|
local pg_hba=/etc/postgresql/9.6/main/pg_hba.conf
|
||||||
|
local logfile=/var/log/postgresql/postgresql-9.6-main.log
|
||||||
|
else
|
||||||
|
if dpkg --list | grep -q "ii postgresql-9."
|
||||||
|
then
|
||||||
|
ynh_die "It looks like postgresql was not properly configured ? /etc/postgresql/9.* is missing ... Could be due to a locale issue, c.f.https://serverfault.com/questions/426989/postgresql-etc-postgresql-doesnt-exist"
|
||||||
|
else
|
||||||
|
ynh_die "postgresql shoud be 9.4 or 9.6"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# force all user to connect to local databases using hashed passwords
|
ynh_systemd_action --service_name=postgresql --action=start
|
||||||
# https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html#EXAMPLE-PG-HBA.CONF
|
|
||||||
# Note: we can't use peer since YunoHost create users with nologin
|
|
||||||
# See: https://github.com/YunoHost/yunohost/blob/unstable/data/helpers.d/user
|
|
||||||
ynh_replace_string --match_string="local\(\s*\)all\(\s*\)all\(\s*\)peer" --replace_string="local\1all\2all\3md5" --target_file="$pg_hba"
|
|
||||||
|
|
||||||
# Advertise service in admin panel
|
sudo --login --user=postgres psql -c"ALTER user postgres WITH PASSWORD '$psql_root_password'" postgres
|
||||||
yunohost service add postgresql --log "$logfile"
|
|
||||||
|
|
||||||
systemctl enable postgresql
|
# force all user to connect to local databases using hashed passwords
|
||||||
ynh_systemd_action --service_name=postgresql --action=reload
|
# https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html#EXAMPLE-PG-HBA.CONF
|
||||||
fi
|
# Note: we can't use peer since YunoHost create users with nologin
|
||||||
|
# See: https://github.com/YunoHost/yunohost/blob/unstable/data/helpers.d/user
|
||||||
|
ynh_replace_string --match_string="local\(\s*\)all\(\s*\)all\(\s*\)peer" --replace_string="local\1all\2all\3md5" --target_file="$pg_hba"
|
||||||
|
|
||||||
|
# Advertise service in admin panel
|
||||||
|
yunohost service add postgresql --log "$logfile"
|
||||||
|
|
||||||
|
systemctl enable postgresql
|
||||||
|
ynh_systemd_action --service_name=postgresql --action=reload
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
# Get an application setting
|
# Get an application setting
|
||||||
#
|
#
|
||||||
# usage: ynh_app_setting_get --app=app --key=key
|
# usage: ynh_app_setting_get --app=app --key=key
|
||||||
# | arg: -a, --app - the application id
|
# | arg: -a, --app= - the application id
|
||||||
# | arg: -k, --key - the setting to get
|
# | arg: -k, --key= - the setting to get
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_app_setting_get() {
|
ynh_app_setting_get() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=ak
|
local legacy_args=ak
|
||||||
declare -Ar args_array=( [a]=app= [k]=key= )
|
local -A args_array=( [a]=app= [k]=key= )
|
||||||
local app
|
local app
|
||||||
local key
|
local key
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
|
@ -22,15 +22,15 @@ ynh_app_setting_get() {
|
||||||
# Set an application setting
|
# Set an application setting
|
||||||
#
|
#
|
||||||
# usage: ynh_app_setting_set --app=app --key=key --value=value
|
# usage: ynh_app_setting_set --app=app --key=key --value=value
|
||||||
# | arg: -a, --app - the application id
|
# | arg: -a, --app= - the application id
|
||||||
# | arg: -k, --key - the setting name to set
|
# | arg: -k, --key= - the setting name to set
|
||||||
# | arg: -v, --value - the setting value to set
|
# | arg: -v, --value= - the setting value to set
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_app_setting_set() {
|
ynh_app_setting_set() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=akv
|
local legacy_args=akv
|
||||||
declare -Ar args_array=( [a]=app= [k]=key= [v]=value= )
|
local -A args_array=( [a]=app= [k]=key= [v]=value= )
|
||||||
local app
|
local app
|
||||||
local key
|
local key
|
||||||
local value
|
local value
|
||||||
|
@ -43,14 +43,14 @@ ynh_app_setting_set() {
|
||||||
# Delete an application setting
|
# Delete an application setting
|
||||||
#
|
#
|
||||||
# usage: ynh_app_setting_delete --app=app --key=key
|
# usage: ynh_app_setting_delete --app=app --key=key
|
||||||
# | arg: -a, --app - the application id
|
# | arg: -a, --app= - the application id
|
||||||
# | arg: -k, --key - the setting to delete
|
# | arg: -k, --key= - the setting to delete
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_app_setting_delete() {
|
ynh_app_setting_delete() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=ak
|
local legacy_args=ak
|
||||||
declare -Ar args_array=( [a]=app= [k]=key= )
|
local -A args_array=( [a]=app= [k]=key= )
|
||||||
local app
|
local app
|
||||||
local key
|
local key
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
|
@ -59,98 +59,6 @@ ynh_app_setting_delete() {
|
||||||
ynh_app_setting "delete" "$app" "$key"
|
ynh_app_setting "delete" "$app" "$key"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add skipped_uris urls into the config
|
|
||||||
#
|
|
||||||
# usage: ynh_add_skipped_uris [--appid=app] --url=url1,url2 [--regex]
|
|
||||||
# | arg: -a, --appid - the application id
|
|
||||||
# | arg: -u, --url - the urls to add to the sso for this app
|
|
||||||
# | arg: -r, --regex - Use the key 'skipped_regex' instead of 'skipped_uris'
|
|
||||||
#
|
|
||||||
# An URL set with 'skipped_uris' key will be totally ignored by the SSO,
|
|
||||||
# which means that the access will be public and the logged-in user information will not be passed to the app.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.6.0 or higher.
|
|
||||||
ynh_add_skipped_uris() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=aur
|
|
||||||
declare -Ar args_array=( [a]=appid= [u]=url= [r]=regex )
|
|
||||||
local appid
|
|
||||||
local url
|
|
||||||
local regex
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
appid={appid:-$app}
|
|
||||||
regex={regex:-0}
|
|
||||||
|
|
||||||
local key=skipped_uris
|
|
||||||
if [ $regex -eq 1 ]; then
|
|
||||||
key=skipped_regex
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_app_setting_set --app=$appid --key=$key --value="$url"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add unprotected_uris urls into the config
|
|
||||||
#
|
|
||||||
# usage: ynh_add_unprotected_uris [--appid=app] --url=url1,url2 [--regex]
|
|
||||||
# | arg: -a, --appid - the application id
|
|
||||||
# | arg: -u, --url - the urls to add to the sso for this app
|
|
||||||
# | arg: -r, --regex - Use the key 'unprotected_regex' instead of 'unprotected_uris'
|
|
||||||
#
|
|
||||||
# An URL set with unprotected_uris key will be accessible publicly, but if an user is logged in,
|
|
||||||
# his information will be accessible (through HTTP headers) to the app.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.6.0 or higher.
|
|
||||||
ynh_add_unprotected_uris() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=aur
|
|
||||||
declare -Ar args_array=( [a]=appid= [u]=url= [r]=regex )
|
|
||||||
local appid
|
|
||||||
local url
|
|
||||||
local regex
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
appid={appid:-$app}
|
|
||||||
regex={regex:-0}
|
|
||||||
|
|
||||||
local key=unprotected_uris
|
|
||||||
if [ $regex -eq 1 ]; then
|
|
||||||
key=unprotected_regex
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_app_setting_set --app=$appid --key=$key --value="$url"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add protected_uris urls into the config
|
|
||||||
#
|
|
||||||
# usage: ynh_add_protected_uris [--appid=app] --url=url1,url2 [--regex]
|
|
||||||
# | arg: -a, --appid - the application id
|
|
||||||
# | arg: -u, --url - the urls to add to the sso for this app
|
|
||||||
# | arg: -r, --regex - Use the key 'protected_regex' instead of 'protected_uris'
|
|
||||||
#
|
|
||||||
# An URL set with protected_uris will be blocked by the SSO and accessible only to authenticated and authorized users.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.6.0 or higher.
|
|
||||||
ynh_add_protected_uris() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=aur
|
|
||||||
declare -Ar args_array=( [a]=appid= [u]=url= [r]=regex )
|
|
||||||
local appid
|
|
||||||
local url
|
|
||||||
local regex
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
appid={appid:-$app}
|
|
||||||
regex={regex:-0}
|
|
||||||
|
|
||||||
local key=protected_uris
|
|
||||||
if [ $regex -eq 1 ]; then
|
|
||||||
key=protected_regex
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_app_setting_set --app=$appid --key=$key --value="$url"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Small "hard-coded" interface to avoid calling "yunohost app" directly each
|
# Small "hard-coded" interface to avoid calling "yunohost app" directly each
|
||||||
# time dealing with a setting is needed (which may be so slow on ARM boards)
|
# time dealing with a setting is needed (which may be so slow on ARM boards)
|
||||||
#
|
#
|
||||||
|
@ -158,8 +66,13 @@ ynh_add_protected_uris() {
|
||||||
#
|
#
|
||||||
ynh_app_setting()
|
ynh_app_setting()
|
||||||
{
|
{
|
||||||
ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python - <<EOF
|
if [[ "$1" == "delete" ]] && [[ "$3" =~ ^(unprotected|skipped)_ ]]
|
||||||
import os, yaml
|
then
|
||||||
|
current_value=$(ynh_app_setting_get --app=$app --key=$3)
|
||||||
|
fi
|
||||||
|
|
||||||
|
ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python2.7 - <<EOF
|
||||||
|
import os, yaml, sys
|
||||||
app, action = os.environ['APP'], os.environ['ACTION'].lower()
|
app, action = os.environ['APP'], os.environ['ACTION'].lower()
|
||||||
key, value = os.environ['KEY'], os.environ.get('VALUE', None)
|
key, value = os.environ['KEY'], os.environ.get('VALUE', None)
|
||||||
setting_file = "/etc/yunohost/apps/%s/settings.yml" % app
|
setting_file = "/etc/yunohost/apps/%s/settings.yml" % app
|
||||||
|
@ -176,12 +89,27 @@ else:
|
||||||
elif action == "set":
|
elif action == "set":
|
||||||
if key in ['redirected_urls', 'redirected_regex']:
|
if key in ['redirected_urls', 'redirected_regex']:
|
||||||
value = yaml.load(value)
|
value = yaml.load(value)
|
||||||
|
if any(key.startswith(word+"_") for word in ["unprotected", "protected", "skipped"]):
|
||||||
|
sys.stderr.write("/!\\ Packagers! This app is still using the skipped/protected/unprotected_uris/regex settings which are now obsolete and deprecated... Instead, you should use the new helpers 'ynh_permission_{create,urls,update,delete}' and the 'visitors' group to initialize the public/private access. Check out the documentation at the bottom of yunohost.org/groups_and_permissions to learn how to use the new permission mechanism.\n")
|
||||||
settings[key] = value
|
settings[key] = value
|
||||||
else:
|
else:
|
||||||
raise ValueError("action should either be get, set or delete")
|
raise ValueError("action should either be get, set or delete")
|
||||||
with open(setting_file, "w") as f:
|
with open(setting_file, "w") as f:
|
||||||
yaml.safe_dump(settings, f, default_flow_style=False)
|
yaml.safe_dump(settings, f, default_flow_style=False)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# Fucking legacy permission management.
|
||||||
|
# We need this because app temporarily set the app as unprotected to configure it with curl...
|
||||||
|
if [[ "$3" =~ ^(unprotected|skipped)_ ]]
|
||||||
|
then
|
||||||
|
if [[ "$1" == "set" ]] && [[ "${4:-}" == "/" ]]
|
||||||
|
then
|
||||||
|
ynh_permission_update --permission "main" --add "visitors"
|
||||||
|
elif [[ "$1" == "delete" ]] && [[ "${current_value:-}" == "/" ]] && [[ -n "$(ynh_app_setting_get --app=$2 --key='is_public' )" ]]
|
||||||
|
then
|
||||||
|
ynh_permission_update --permission "main" --remove "visitors"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check availability of a web path
|
# Check availability of a web path
|
||||||
|
@ -189,20 +117,20 @@ EOF
|
||||||
# example: ynh_webpath_available --domain=some.domain.tld --path_url=/coffee
|
# example: ynh_webpath_available --domain=some.domain.tld --path_url=/coffee
|
||||||
#
|
#
|
||||||
# usage: ynh_webpath_available --domain=domain --path_url=path
|
# usage: ynh_webpath_available --domain=domain --path_url=path
|
||||||
# | arg: -d, --domain - the domain/host of the url
|
# | arg: -d, --domain= - the domain/host of the url
|
||||||
# | arg: -p, --path_url - the web path to check the availability of
|
# | arg: -p, --path_url= - the web path to check the availability of
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_webpath_available () {
|
ynh_webpath_available () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=dp
|
local legacy_args=dp
|
||||||
declare -Ar args_array=( [d]=domain= [p]=path_url= )
|
local -A args_array=( [d]=domain= [p]=path_url= )
|
||||||
local domain
|
local domain
|
||||||
local path_url
|
local path_url
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
sudo yunohost domain url-available $domain $path_url
|
yunohost domain url-available $domain $path_url
|
||||||
}
|
}
|
||||||
|
|
||||||
# Register/book a web path for an app
|
# Register/book a web path for an app
|
||||||
|
@ -210,90 +138,186 @@ ynh_webpath_available () {
|
||||||
# example: ynh_webpath_register --app=wordpress --domain=some.domain.tld --path_url=/coffee
|
# example: ynh_webpath_register --app=wordpress --domain=some.domain.tld --path_url=/coffee
|
||||||
#
|
#
|
||||||
# usage: ynh_webpath_register --app=app --domain=domain --path_url=path
|
# usage: ynh_webpath_register --app=app --domain=domain --path_url=path
|
||||||
# | arg: -a, --app - the app for which the domain should be registered
|
# | arg: -a, --app= - the app for which the domain should be registered
|
||||||
# | arg: -d, --domain - the domain/host of the web path
|
# | arg: -d, --domain= - the domain/host of the web path
|
||||||
# | arg: -p, --path_url - the web path to be registered
|
# | arg: -p, --path_url= - the web path to be registered
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_webpath_register () {
|
ynh_webpath_register () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=adp
|
local legacy_args=adp
|
||||||
declare -Ar args_array=( [a]=app= [d]=domain= [p]=path_url= )
|
local -A args_array=( [a]=app= [d]=domain= [p]=path_url= )
|
||||||
local app
|
local app
|
||||||
local domain
|
local domain
|
||||||
local path_url
|
local path_url
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
sudo yunohost app register-url $app $domain $path_url
|
yunohost app register-url $app $domain $path_url
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a new permission for the app
|
# Create a new permission for the app
|
||||||
#
|
#
|
||||||
# usage: ynh_permission_create --app "app" --permission "permission" --defaultdisallow [--urls "url" ["url" ...]]
|
# example: ynh_permission_create --permission=admin --url=/admin --allowed="alice bob"
|
||||||
# | arg: app - the application id
|
#
|
||||||
# | arg: permission - the name for the permission (by default a permission named "main" already exist)
|
# usage: ynh_permission_create --permission "permission" [--url=url] [--allowed="group1 group2"]
|
||||||
# | arg: defaultdisallow - define if all user will be allowed by default
|
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist)
|
||||||
# | arg: urls - the list of urls for the the permission
|
# | arg: -u, --url= - (optional) URL for which access will be allowed/forbidden
|
||||||
|
# | arg: -a, --allowed= - (optional) A list of group/user to allow for the permission
|
||||||
|
#
|
||||||
|
# If provided, 'url' is assumed to be relative to the app domain/path if they
|
||||||
|
# start with '/'. For example:
|
||||||
|
# / -> domain.tld/app
|
||||||
|
# /admin -> domain.tld/app/admin
|
||||||
|
# domain.tld/app/api -> domain.tld/app/api
|
||||||
|
#
|
||||||
|
# 'url' can be later treated as a regex if it starts with "re:".
|
||||||
|
# For example:
|
||||||
|
# re:/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$
|
||||||
|
# re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.7.0 or higher.
|
||||||
ynh_permission_create() {
|
ynh_permission_create() {
|
||||||
declare -Ar args_array=( [a]=app= [p]=permission= [d]=defaultdisallow [u]=urls= )
|
# Declare an array to define the options of this helper.
|
||||||
local app
|
local legacy_args=pua
|
||||||
|
local -A args_array=( [p]=permission= [u]=url= [a]=allowed= )
|
||||||
local permission
|
local permission
|
||||||
local defaultdisallow
|
local url
|
||||||
local urls
|
local allowed
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
if [[ -n ${defaultdisallow:-} ]]; then
|
url=${url:-}
|
||||||
defaultdisallow=",default_allow=False"
|
allowed=${allowed:-}
|
||||||
|
|
||||||
|
if [[ -n $url ]]
|
||||||
|
then
|
||||||
|
url="'$url'"
|
||||||
|
else
|
||||||
|
url="None"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n ${urls:-} ]]; then
|
if [[ -n $allowed ]]; then
|
||||||
urls=",urls=['${urls//';'/"','"}']"
|
allowed=",allowed=['${allowed//';'/"','"}']"
|
||||||
fi
|
fi
|
||||||
yunohost tools shell -c "from yunohost.permission import permission_add; permission_add('$app', '$permission' ${defaultdisallow:-} ${urls:-}, sync_perm=False)"
|
|
||||||
|
yunohost tools shell -c "from yunohost.permission import permission_create; permission_create('$app.$permission', url=$url $allowed , sync_perm=False)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove a permission for the app (note that when the app is removed all permission is automatically removed)
|
# Remove a permission for the app (note that when the app is removed all permission is automatically removed)
|
||||||
#
|
#
|
||||||
# usage: ynh_permission_remove --app "app" --permission "permission"
|
# example: ynh_permission_delete --permission=editors
|
||||||
# | arg: app - the application id
|
#
|
||||||
# | arg: permission - the name for the permission (by default a permission named "main" is removed automatically when the app is removed)
|
# usage: ynh_permission_delete --permission="permission"
|
||||||
ynh_permission_remove() {
|
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed)
|
||||||
declare -Ar args_array=( [a]=app= [p]=permission= )
|
#
|
||||||
local app
|
# Requires YunoHost version 3.7.0 or higher.
|
||||||
|
ynh_permission_delete() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=p
|
||||||
|
local -A args_array=( [p]=permission= )
|
||||||
local permission
|
local permission
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
yunohost tools shell -c "from yunohost.permission import permission_remove; permission_remove('$app', '$permission', sync_perm=False)"
|
yunohost tools shell -c "from yunohost.permission import permission_delete; permission_delete('$app.$permission', sync_perm=False)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add a path managed by the SSO
|
# Check if a permission exists
|
||||||
#
|
#
|
||||||
# usage: ynh_permission_add_path --app "app" --permission "permission" --url "url" ["url" ...]
|
# usage: ynh_permission_exists --permission=permission
|
||||||
# | arg: app - the application id
|
# | arg: -p, --permission= - the permission to check
|
||||||
# | arg: permission - the name for the permission
|
# | exit: Return 1 if the permission doesn't exist, 0 otherwise
|
||||||
# | arg: url - the FULL url for the the permission (ex domain.tld/apps/admin)
|
#
|
||||||
ynh_permission_add_path() {
|
# Requires YunoHost version 3.7.0 or higher.
|
||||||
declare -Ar args_array=( [a]=app= [p]=permission= [u]=url= )
|
ynh_permission_exists() {
|
||||||
local app
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=p
|
||||||
|
local -A args_array=( [p]=permission= )
|
||||||
|
local permission
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
yunohost user permission list --short | grep --word-regexp --quiet "$app.$permission"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redefine the url associated to a permission
|
||||||
|
#
|
||||||
|
# usage: ynh_permission_url --permission="permission" [--url="url"]
|
||||||
|
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed)
|
||||||
|
# | arg: -u, --url= - (optional) URL for which access will be allowed/forbidden
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.7.0 or higher.
|
||||||
|
ynh_permission_url() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=pu
|
||||||
|
local -A args_array=([p]=permission= [u]=url=)
|
||||||
local permission
|
local permission
|
||||||
local url
|
local url
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
url=${url:-}
|
||||||
|
|
||||||
yunohost tools shell -c "from yunohost.permission import permission_update; permission_update('$app', '$permission', add_url=['${url//';'/"','"}'], sync_perm=False)"
|
if [[ -n $url ]]
|
||||||
|
then
|
||||||
|
url="'$url'"
|
||||||
|
else
|
||||||
|
url="None"
|
||||||
|
fi
|
||||||
|
|
||||||
|
yunohost tools shell -c "from yunohost.permission import permission_url; permission_url('$app.$permission', url=$url)"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove a path managed by the SSO
|
|
||||||
|
# Update a permission for the app
|
||||||
#
|
#
|
||||||
# usage: ynh_permission_del_path --app "app" --permission "permission" --url "url" ["url" ...]
|
# example: ynh_permission_update --permission admin --add=samdoe --remove=all_users
|
||||||
# | arg: app - the application id
|
#
|
||||||
# | arg: permission - the name for the permission
|
# usage: ynh_permission_update --permission="permission" [--add="group1 group2"] [--remove="group1 group2"]
|
||||||
# | arg: url - the FULL url for the the permission (ex domain.tld/apps/admin)
|
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist)
|
||||||
ynh_permission_del_path() {
|
# | arg: -a, --add= - the list of group or users to enable add to the permission
|
||||||
declare -Ar args_array=( [a]=app= [p]=permission= [u]=url= )
|
# | arg: -r, --remove= - the list of group or users to remove from the permission
|
||||||
local app
|
#
|
||||||
|
# Requires YunoHost version 3.7.0 or higher.
|
||||||
|
ynh_permission_update() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=par
|
||||||
|
local -A args_array=( [p]=permission= [a]=add= [r]=remove= )
|
||||||
local permission
|
local permission
|
||||||
local url
|
local add
|
||||||
|
local remove
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
add=${add:-}
|
||||||
|
remove=${remove:-}
|
||||||
|
|
||||||
|
if [[ -n $add ]]; then
|
||||||
|
add="--add ${add//';'/" "}"
|
||||||
|
fi
|
||||||
|
if [[ -n $remove ]]; then
|
||||||
|
remove="--remove ${remove//';'/" "} "
|
||||||
|
fi
|
||||||
|
|
||||||
|
yunohost user permission update "$app.$permission" $add $remove
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if a permission has an user
|
||||||
|
#
|
||||||
|
# example: ynh_permission_has_user --permission=main --user=visitors
|
||||||
|
#
|
||||||
|
# usage: ynh_permission_has_user --permission=permission --user=user
|
||||||
|
# | arg: -p, --permission= - the permission to check
|
||||||
|
# | arg: -u, --user= - the user seek in the permission
|
||||||
|
# | exit: Return 1 if the permission doesn't have that user or doesn't exist, 0 otherwise
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.7.1 or higher.
|
||||||
|
ynh_permission_has_user() {
|
||||||
|
local legacy_args=pu
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local -A args_array=( [p]=permission= [u]=user= )
|
||||||
|
local permission
|
||||||
|
local user
|
||||||
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
yunohost tools shell -c "from yunohost.permission import permission_update; permission_update('$app', '$permission', remove_url=['${url//';'/"','"}'], sync_perm=False)"
|
if ! ynh_permission_exists --permission=$permission
|
||||||
|
then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
yunohost user permission info "$app.$permission" | grep --word-regexp --quiet "$user"
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,29 +5,30 @@
|
||||||
# example: pwd=$(ynh_string_random --length=8)
|
# example: pwd=$(ynh_string_random --length=8)
|
||||||
#
|
#
|
||||||
# usage: ynh_string_random [--length=string_length]
|
# usage: ynh_string_random [--length=string_length]
|
||||||
# | arg: -l, --length - the string length to generate (default: 24)
|
# | arg: -l, --length= - the string length to generate (default: 24)
|
||||||
|
# | ret: the generated string
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_string_random() {
|
ynh_string_random() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=l
|
local legacy_args=l
|
||||||
declare -Ar args_array=( [l]=length= )
|
local -A args_array=( [l]=length= )
|
||||||
local length
|
local length
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
length=${length:-24}
|
length=${length:-24}
|
||||||
|
|
||||||
dd if=/dev/urandom bs=1 count=1000 2> /dev/null \
|
dd if=/dev/urandom bs=1 count=1000 2> /dev/null \
|
||||||
| tr -c -d 'A-Za-z0-9' \
|
| tr --complement --delete 'A-Za-z0-9' \
|
||||||
| sed -n 's/\(.\{'"$length"'\}\).*/\1/p'
|
| sed --quiet 's/\(.\{'"$length"'\}\).*/\1/p'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Substitute/replace a string (or expression) by another in a file
|
# Substitute/replace a string (or expression) by another in a file
|
||||||
#
|
#
|
||||||
# usage: ynh_replace_string --match_string=match_string --replace_string=replace_string --target_file=target_file
|
# usage: ynh_replace_string --match_string=match_string --replace_string=replace_string --target_file=target_file
|
||||||
# | arg: -m, --match_string - String to be searched and replaced in the file
|
# | arg: -m, --match_string= - String to be searched and replaced in the file
|
||||||
# | arg: -r, --replace_string - String that will replace matches
|
# | arg: -r, --replace_string= - String that will replace matches
|
||||||
# | arg: -f, --target_file - File in which the string will be replaced.
|
# | arg: -f, --target_file= - File in which the string will be replaced.
|
||||||
#
|
#
|
||||||
# As this helper is based on sed command, regular expressions and
|
# As this helper is based on sed command, regular expressions and
|
||||||
# references to sub-expressions can be used
|
# references to sub-expressions can be used
|
||||||
|
@ -35,53 +36,53 @@ ynh_string_random() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_replace_string () {
|
ynh_replace_string () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=mrf
|
local legacy_args=mrf
|
||||||
declare -Ar args_array=( [m]=match_string= [r]=replace_string= [f]=target_file= )
|
local -A args_array=( [m]=match_string= [r]=replace_string= [f]=target_file= )
|
||||||
local match_string
|
local match_string
|
||||||
local replace_string
|
local replace_string
|
||||||
local target_file
|
local target_file
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
local delimit=@
|
local delimit=@
|
||||||
# Escape the delimiter if it's in the string.
|
# Escape the delimiter if it's in the string.
|
||||||
match_string=${match_string//${delimit}/"\\${delimit}"}
|
match_string=${match_string//${delimit}/"\\${delimit}"}
|
||||||
replace_string=${replace_string//${delimit}/"\\${delimit}"}
|
replace_string=${replace_string//${delimit}/"\\${delimit}"}
|
||||||
|
|
||||||
sudo sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$target_file"
|
sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$target_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Substitute/replace a special string by another in a file
|
# Substitute/replace a special string by another in a file
|
||||||
#
|
#
|
||||||
# usage: ynh_replace_special_string --match_string=match_string --replace_string=replace_string --target_file=target_file
|
# usage: ynh_replace_special_string --match_string=match_string --replace_string=replace_string --target_file=target_file
|
||||||
# | arg: -m, --match_string - String to be searched and replaced in the file
|
# | arg: -m, --match_string= - String to be searched and replaced in the file
|
||||||
# | arg: -r, --replace_string - String that will replace matches
|
# | arg: -r, --replace_string= - String that will replace matches
|
||||||
# | arg: -t, --target_file - File in which the string will be replaced.
|
# | arg: -t, --target_file= - File in which the string will be replaced.
|
||||||
#
|
#
|
||||||
# This helper will use ynh_replace_string, but as you can use special
|
# This helper will use ynh_replace_string, but as you can use special
|
||||||
# characters, you can't use some regular expressions and sub-expressions.
|
# characters, you can't use some regular expressions and sub-expressions.
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.7 or higher.
|
# Requires YunoHost version 2.7.7 or higher.
|
||||||
ynh_replace_special_string () {
|
ynh_replace_special_string () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=mrf
|
local legacy_args=mrf
|
||||||
declare -Ar args_array=( [m]=match_string= [r]=replace_string= [f]=target_file= )
|
local -A args_array=( [m]=match_string= [r]=replace_string= [f]=target_file= )
|
||||||
local match_string
|
local match_string
|
||||||
local replace_string
|
local replace_string
|
||||||
local target_file
|
local target_file
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
# Escape any backslash to preserve them as simple backslash.
|
# Escape any backslash to preserve them as simple backslash.
|
||||||
match_string=${match_string//\\/"\\\\"}
|
match_string=${match_string//\\/"\\\\"}
|
||||||
replace_string=${replace_string//\\/"\\\\"}
|
replace_string=${replace_string//\\/"\\\\"}
|
||||||
|
|
||||||
# Escape the & character, who has a special function in sed.
|
# Escape the & character, who has a special function in sed.
|
||||||
match_string=${match_string//&/"\&"}
|
match_string=${match_string//&/"\&"}
|
||||||
replace_string=${replace_string//&/"\&"}
|
replace_string=${replace_string//&/"\&"}
|
||||||
|
|
||||||
ynh_replace_string --match_string="$match_string" --replace_string="$replace_string" --target_file="$target_file"
|
ynh_replace_string --match_string="$match_string" --replace_string="$replace_string" --target_file="$target_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Sanitize a string intended to be the name of a database
|
# Sanitize a string intended to be the name of a database
|
||||||
|
@ -90,24 +91,26 @@ ynh_replace_special_string () {
|
||||||
# example: dbname=$(ynh_sanitize_dbid $app)
|
# example: dbname=$(ynh_sanitize_dbid $app)
|
||||||
#
|
#
|
||||||
# usage: ynh_sanitize_dbid --db_name=name
|
# usage: ynh_sanitize_dbid --db_name=name
|
||||||
# | arg: -n, --db_name - name to correct/sanitize
|
# | arg: -n, --db_name= - name to correct/sanitize
|
||||||
# | ret: the corrected name
|
# | ret: the corrected name
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_sanitize_dbid () {
|
ynh_sanitize_dbid () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=n
|
local legacy_args=n
|
||||||
declare -Ar args_array=( [n]=db_name= )
|
local -A args_array=( [n]=db_name= )
|
||||||
local db_name
|
local db_name
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
# We should avoid having - and . in the name of databases. They are replaced by _
|
# We should avoid having - and . in the name of databases. They are replaced by _
|
||||||
echo ${db_name//[-.]/_}
|
echo ${db_name//[-.]/_}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Normalize the url path syntax
|
# Normalize the url path syntax
|
||||||
#
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
# Handle the slash at the beginning of path and its absence at ending
|
# Handle the slash at the beginning of path and its absence at ending
|
||||||
# Return a normalized url path
|
# Return a normalized url path
|
||||||
#
|
#
|
||||||
|
@ -119,23 +122,23 @@ ynh_sanitize_dbid () {
|
||||||
# ynh_normalize_url_path / # -> /
|
# ynh_normalize_url_path / # -> /
|
||||||
#
|
#
|
||||||
# usage: ynh_normalize_url_path --path_url=path_to_normalize
|
# usage: ynh_normalize_url_path --path_url=path_to_normalize
|
||||||
# | arg: -p, --path_url - URL path to normalize before using it
|
# | arg: -p, --path_url= - URL path to normalize before using it
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_normalize_url_path () {
|
ynh_normalize_url_path () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=p
|
local legacy_args=p
|
||||||
declare -Ar args_array=( [p]=path_url= )
|
local -A args_array=( [p]=path_url= )
|
||||||
local path_url
|
local path_url
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
test -n "$path_url" || ynh_die --message="ynh_normalize_url_path expect a URL path as first argument and received nothing."
|
test -n "$path_url" || ynh_die --message="ynh_normalize_url_path expect a URL path as first argument and received nothing."
|
||||||
if [ "${path_url:0:1}" != "/" ]; then # If the first character is not a /
|
if [ "${path_url:0:1}" != "/" ]; then # If the first character is not a /
|
||||||
path_url="/$path_url" # Add / at begin of path variable
|
path_url="/$path_url" # Add / at begin of path variable
|
||||||
fi
|
fi
|
||||||
if [ "${path_url:${#path_url}-1}" == "/" ] && [ ${#path_url} -gt 1 ]; then # If the last character is a / and that not the only character.
|
if [ "${path_url:${#path_url}-1}" == "/" ] && [ ${#path_url} -gt 1 ]; then # If the last character is a / and that not the only character.
|
||||||
path_url="${path_url:0:${#path_url}-1}" # Delete the last character
|
path_url="${path_url:0:${#path_url}-1}" # Delete the last character
|
||||||
fi
|
fi
|
||||||
echo $path_url
|
echo $path_url
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
# Create a dedicated systemd config
|
# Create a dedicated systemd config
|
||||||
#
|
#
|
||||||
# usage: ynh_add_systemd_config [--service=service] [--template=template]
|
# usage: ynh_add_systemd_config [--service=service] [--template=template]
|
||||||
# | arg: -s, --service - Service name (optionnal, $app by default)
|
# | arg: -s, --service= - Service name (optionnal, $app by default)
|
||||||
# | arg: -t, --template - Name of template file (optionnal, this is 'systemd' by default, meaning ./conf/systemd.service will be used as template)
|
# | arg: -t, --template= - Name of template file (optionnal, this is 'systemd' by default, meaning ./conf/systemd.service will be used as template)
|
||||||
#
|
#
|
||||||
# This will use the template ../conf/<templatename>.service
|
# This will use the template ../conf/<templatename>.service
|
||||||
# to generate a systemd config, by replacing the following keywords
|
# to generate a systemd config, by replacing the following keywords
|
||||||
|
@ -14,103 +14,106 @@
|
||||||
# __APP__ by $app
|
# __APP__ by $app
|
||||||
# __FINALPATH__ by $final_path
|
# __FINALPATH__ by $final_path
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# Requires YunoHost version 2.7.11 or higher.
|
||||||
ynh_add_systemd_config () {
|
ynh_add_systemd_config () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=st
|
local legacy_args=st
|
||||||
declare -Ar args_array=( [s]=service= [t]=template= )
|
local -A args_array=( [s]=service= [t]=template= )
|
||||||
local service
|
local service
|
||||||
local template
|
local template
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
local service="${service:-$app}"
|
local service="${service:-$app}"
|
||||||
local template="${template:-systemd.service}"
|
local template="${template:-systemd.service}"
|
||||||
|
|
||||||
finalsystemdconf="/etc/systemd/system/$service.service"
|
finalsystemdconf="/etc/systemd/system/$service.service"
|
||||||
ynh_backup_if_checksum_is_different --file="$finalsystemdconf"
|
ynh_backup_if_checksum_is_different --file="$finalsystemdconf"
|
||||||
sudo cp ../conf/$template "$finalsystemdconf"
|
cp ../conf/$template "$finalsystemdconf"
|
||||||
|
|
||||||
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
||||||
# Substitute in a nginx config file only if the variable is not empty
|
# Substitute in a nginx config file only if the variable is not empty
|
||||||
if test -n "${final_path:-}"; then
|
if [ -n "${final_path:-}" ]; then
|
||||||
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalsystemdconf"
|
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalsystemdconf"
|
||||||
fi
|
fi
|
||||||
if test -n "${app:-}"; then
|
if [ -n "${app:-}" ]; then
|
||||||
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$finalsystemdconf"
|
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$finalsystemdconf"
|
||||||
fi
|
fi
|
||||||
ynh_store_file_checksum --file="$finalsystemdconf"
|
ynh_store_file_checksum --file="$finalsystemdconf"
|
||||||
|
|
||||||
sudo chown root: "$finalsystemdconf"
|
chown root: "$finalsystemdconf"
|
||||||
sudo systemctl enable $service
|
systemctl enable $service
|
||||||
sudo systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove the dedicated systemd config
|
# Remove the dedicated systemd config
|
||||||
#
|
#
|
||||||
# usage: ynh_remove_systemd_config [--service=service]
|
# usage: ynh_remove_systemd_config [--service=service]
|
||||||
# | arg: -s, --service - Service name (optionnal, $app by default)
|
# | arg: -s, --service= - Service name (optionnal, $app by default)
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
ynh_remove_systemd_config () {
|
ynh_remove_systemd_config () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=s
|
local legacy_args=s
|
||||||
declare -Ar args_array=( [s]=service= )
|
local -A args_array=( [s]=service= )
|
||||||
local service
|
local service
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
local service="${service:-$app}"
|
local service="${service:-$app}"
|
||||||
|
|
||||||
local finalsystemdconf="/etc/systemd/system/$service.service"
|
local finalsystemdconf="/etc/systemd/system/$service.service"
|
||||||
if [ -e "$finalsystemdconf" ]; then
|
if [ -e "$finalsystemdconf" ]
|
||||||
ynh_systemd_action --service_name=$service --action=stop
|
then
|
||||||
systemctl disable $service
|
ynh_systemd_action --service_name=$service --action=stop
|
||||||
ynh_secure_remove --file="$finalsystemdconf"
|
systemctl disable $service
|
||||||
systemctl daemon-reload
|
ynh_secure_remove --file="$finalsystemdconf"
|
||||||
fi
|
systemctl daemon-reload
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start (or other actions) a service, print a log in case of failure and optionnaly wait until the service is completely started
|
# Start (or other actions) a service, print a log in case of failure and optionnaly wait until the service is completely started
|
||||||
#
|
#
|
||||||
# usage: ynh_systemd_action [-n service_name] [-a action] [ [-l "line to match"] [-p log_path] [-t timeout] [-e length] ]
|
# usage: ynh_systemd_action [--service_name=service_name] [--action=action] [ [--line_match="line to match"] [--log_path=log_path] [--timeout=300] [--length=20] ]
|
||||||
# | arg: -n, --service_name= - Name of the service to start. Default : $app
|
# | arg: -n, --service_name= - Name of the service to start. Default : $app
|
||||||
# | arg: -a, --action= - Action to perform with systemctl. Default: start
|
# | arg: -a, --action= - Action to perform with systemctl. Default: start
|
||||||
# | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot. If not defined it don't wait until the service is completely started. WARNING: When using --line_match, you should always add `ynh_clean_check_starting` into your `ynh_clean_setup` at the beginning of the script. Otherwise, tail will not stop in case of failure of the script. The script will then hang forever.
|
# | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot. If not defined it don't wait until the service is completely started. WARNING: When using --line_match, you should always add `ynh_clean_check_starting` into your `ynh_clean_setup` at the beginning of the script. Otherwise, tail will not stop in case of failure of the script. The script will then hang forever.
|
||||||
# | arg: -p, --log_path= - Log file - Path to the log file. Default : /var/log/$app/$app.log
|
# | arg: -p, --log_path= - Log file - Path to the log file. Default : /var/log/$app/$app.log
|
||||||
# | arg: -t, --timeout= - Timeout - The maximum time to wait before ending the watching. Default : 300 seconds.
|
# | arg: -t, --timeout= - Timeout - The maximum time to wait before ending the watching. Default : 300 seconds.
|
||||||
# | arg: -e, --length= - Length of the error log : Default : 20
|
# | arg: -e, --length= - Length of the error log : Default : 20
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_systemd_action() {
|
ynh_systemd_action() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=nalpte
|
local legacy_args=nalpte
|
||||||
declare -Ar args_array=( [n]=service_name= [a]=action= [l]=line_match= [p]=log_path= [t]=timeout= [e]=length= )
|
local -A args_array=( [n]=service_name= [a]=action= [l]=line_match= [p]=log_path= [t]=timeout= [e]=length= )
|
||||||
local service_name
|
local service_name
|
||||||
local action
|
local action
|
||||||
local line_match
|
local line_match
|
||||||
local length
|
local length
|
||||||
local log_path
|
local log_path
|
||||||
local timeout
|
local timeout
|
||||||
|
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
service_name="${service_name:-$app}"
|
||||||
local service_name="${service_name:-$app}"
|
action=${action:-start}
|
||||||
local action=${action:-start}
|
line_match=${line_match:-}
|
||||||
local log_path="${log_path:-/var/log/$service_name/$service_name.log}"
|
length=${length:-20}
|
||||||
local length=${length:-20}
|
log_path="${log_path:-/var/log/$service_name/$service_name.log}"
|
||||||
local timeout=${timeout:-300}
|
timeout=${timeout:-300}
|
||||||
|
|
||||||
# Start to read the log
|
# Start to read the log
|
||||||
if [[ -n "${line_match:-}" ]]
|
if [[ -n "$line_match" ]]
|
||||||
then
|
then
|
||||||
local templog="$(mktemp)"
|
local templog="$(mktemp)"
|
||||||
# Following the starting of the app in its log
|
# Following the starting of the app in its log
|
||||||
if [ "$log_path" == "systemd" ] ; then
|
if [ "$log_path" == "systemd" ]
|
||||||
|
then
|
||||||
# Read the systemd journal
|
# Read the systemd journal
|
||||||
journalctl --unit=$service_name --follow --since=-0 --quiet > "$templog" &
|
journalctl --unit=$service_name --follow --since=-0 --quiet > "$templog" &
|
||||||
# Get the PID of the journalctl command
|
# Get the PID of the journalctl command
|
||||||
local pid_tail=$!
|
local pid_tail=$!
|
||||||
else
|
else
|
||||||
# Read the specified log file
|
# Read the specified log file
|
||||||
tail -F -n0 "$log_path" > "$templog" 2>&1 &
|
tail --follow=name --retry --lines=0 "$log_path" > "$templog" 2>&1 &
|
||||||
# Get the PID of the tail command
|
# Get the PID of the tail command
|
||||||
local pid_tail=$!
|
local pid_tail=$!
|
||||||
fi
|
fi
|
||||||
|
@ -121,10 +124,20 @@ ynh_systemd_action() {
|
||||||
action="reload-or-restart"
|
action="reload-or-restart"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
systemctl $action $service_name \
|
# If the service fails to perform the action
|
||||||
|| ( journalctl --no-pager --lines=$length -u $service_name >&2 \
|
if ! systemctl $action $service_name
|
||||||
; test -e "$log_path" && echo "--" >&2 && tail --lines=$length "$log_path" >&2 \
|
then
|
||||||
; false )
|
# Show syslog for this service
|
||||||
|
ynh_exec_err journalctl --no-pager --lines=$length --unit=$service_name
|
||||||
|
# If a log is specified for this service, show also the content of this log
|
||||||
|
if [ -e "$log_path" ]
|
||||||
|
then
|
||||||
|
ynh_print_err --message="--"
|
||||||
|
ynh_exec_err tail --lines=$length "$log_path"
|
||||||
|
fi
|
||||||
|
# Fail the app script, since the service failed.
|
||||||
|
ynh_die
|
||||||
|
fi
|
||||||
|
|
||||||
# Start the timeout and try to find line_match
|
# Start the timeout and try to find line_match
|
||||||
if [[ -n "${line_match:-}" ]]
|
if [[ -n "${line_match:-}" ]]
|
||||||
|
@ -133,9 +146,9 @@ ynh_systemd_action() {
|
||||||
for i in $(seq 1 $timeout)
|
for i in $(seq 1 $timeout)
|
||||||
do
|
do
|
||||||
# Read the log until the sentence is found, that means the app finished to start. Or run until the timeout
|
# Read the log until the sentence is found, that means the app finished to start. Or run until the timeout
|
||||||
if grep --quiet "$line_match" "$templog"
|
if grep --extended-regexp --quiet "$line_match" "$templog"
|
||||||
then
|
then
|
||||||
ynh_print_info --message="The service $service_name has correctly started."
|
ynh_print_info --message="The service $service_name has correctly executed the action ${action}."
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
if [ $i -eq 3 ]; then
|
if [ $i -eq 3 ]; then
|
||||||
|
@ -151,10 +164,14 @@ ynh_systemd_action() {
|
||||||
fi
|
fi
|
||||||
if [ $i -eq $timeout ]
|
if [ $i -eq $timeout ]
|
||||||
then
|
then
|
||||||
ynh_print_warn --message="The service $service_name didn't fully started before the timeout."
|
ynh_print_warn --message="The service $service_name didn't fully executed the action ${action} before the timeout."
|
||||||
ynh_print_warn --message="Please find here an extract of the end of the log of the service $service_name:"
|
ynh_print_warn --message="Please find here an extract of the end of the log of the service $service_name:"
|
||||||
journalctl --no-pager --lines=$length -u $service_name >&2
|
ynh_exec_warn journalctl --no-pager --lines=$length --unit=$service_name
|
||||||
test -e "$log_path" && echo "--" >&2 && tail --lines=$length "$log_path" >&2
|
if [ -e "$log_path" ]
|
||||||
|
then
|
||||||
|
ynh_print_warn --message="\-\-\-"
|
||||||
|
ynh_exec_warn tail --lines=$length "$log_path"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
ynh_clean_check_starting
|
ynh_clean_check_starting
|
||||||
fi
|
fi
|
||||||
|
@ -164,10 +181,17 @@ ynh_systemd_action() {
|
||||||
# (usually used in ynh_clean_setup scripts)
|
# (usually used in ynh_clean_setup scripts)
|
||||||
#
|
#
|
||||||
# usage: ynh_clean_check_starting
|
# usage: ynh_clean_check_starting
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_clean_check_starting () {
|
ynh_clean_check_starting () {
|
||||||
# Stop the execution of tail.
|
if [ -n "$pid_tail" ]
|
||||||
kill -s 15 $pid_tail 2>&1
|
then
|
||||||
ynh_secure_remove "$templog" 2>&1
|
# Stop the execution of tail.
|
||||||
|
kill -SIGTERM $pid_tail 2>&1
|
||||||
|
fi
|
||||||
|
if [ -n "$templog" ]
|
||||||
|
then
|
||||||
|
ynh_secure_remove "$templog" 2>&1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,18 +5,19 @@
|
||||||
# example: ynh_user_exists 'toto' || exit 1
|
# example: ynh_user_exists 'toto' || exit 1
|
||||||
#
|
#
|
||||||
# usage: ynh_user_exists --username=username
|
# usage: ynh_user_exists --username=username
|
||||||
# | arg: -u, --username - the username to check
|
# | arg: -u, --username= - the username to check
|
||||||
|
# | exit: Return 1 if the user doesn't exist, 0 otherwise
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_user_exists() {
|
ynh_user_exists() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=u
|
local legacy_args=u
|
||||||
declare -Ar args_array=( [u]=username= )
|
local -A args_array=( [u]=username= )
|
||||||
local username
|
local username
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
sudo yunohost user list --output-as json | grep -q "\"username\": \"${username}\""
|
yunohost user list --output-as json | grep --quiet "\"username\": \"${username}\""
|
||||||
}
|
}
|
||||||
|
|
||||||
# Retrieve a YunoHost user information
|
# Retrieve a YunoHost user information
|
||||||
|
@ -24,21 +25,21 @@ ynh_user_exists() {
|
||||||
# example: mail=$(ynh_user_get_info 'toto' 'mail')
|
# example: mail=$(ynh_user_get_info 'toto' 'mail')
|
||||||
#
|
#
|
||||||
# usage: ynh_user_get_info --username=username --key=key
|
# usage: ynh_user_get_info --username=username --key=key
|
||||||
# | arg: -u, --username - the username to retrieve info from
|
# | arg: -u, --username= - the username to retrieve info from
|
||||||
# | arg: -k, --key - the key to retrieve
|
# | arg: -k, --key= - the key to retrieve
|
||||||
# | ret: string - the key's value
|
# | ret: string - the key's value
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_user_get_info() {
|
ynh_user_get_info() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=uk
|
local legacy_args=uk
|
||||||
declare -Ar args_array=( [u]=username= [k]=key= )
|
local -A args_array=( [u]=username= [k]=key= )
|
||||||
local username
|
local username
|
||||||
local key
|
local key
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
sudo yunohost user info "$username" --output-as plain | ynh_get_plain_key "$key"
|
yunohost user info "$username" --output-as plain | ynh_get_plain_key "$key"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get the list of YunoHost users
|
# Get the list of YunoHost users
|
||||||
|
@ -50,20 +51,21 @@ ynh_user_get_info() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.4.0 or higher.
|
# Requires YunoHost version 2.4.0 or higher.
|
||||||
ynh_user_list() {
|
ynh_user_list() {
|
||||||
sudo yunohost user list --output-as plain --quiet \
|
yunohost user list --output-as plain --quiet \
|
||||||
| awk '/^##username$/{getline; print}'
|
| awk '/^##username$/{getline; print}'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if a user exists on the system
|
# Check if a user exists on the system
|
||||||
#
|
#
|
||||||
# usage: ynh_system_user_exists --username=username
|
# usage: ynh_system_user_exists --username=username
|
||||||
# | arg: -u, --username - the username to check
|
# | arg: -u, --username= - the username to check
|
||||||
|
# | exit: Return 1 if the user doesn't exist, 0 otherwise
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_system_user_exists() {
|
ynh_system_user_exists() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=u
|
local legacy_args=u
|
||||||
declare -Ar args_array=( [u]=username= )
|
local -A args_array=( [u]=username= )
|
||||||
local username
|
local username
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
@ -74,11 +76,14 @@ ynh_system_user_exists() {
|
||||||
# Check if a group exists on the system
|
# Check if a group exists on the system
|
||||||
#
|
#
|
||||||
# usage: ynh_system_group_exists --group=group
|
# usage: ynh_system_group_exists --group=group
|
||||||
# | arg: -g, --group - the group to check
|
# | arg: -g, --group= - the group to check
|
||||||
|
# | exit: Return 1 if the group doesn't exist, 0 otherwise
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.5.0.2 or higher.
|
||||||
ynh_system_group_exists() {
|
ynh_system_group_exists() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=g
|
local legacy_args=g
|
||||||
declare -Ar args_array=( [g]=group= )
|
local -A args_array=( [g]=group= )
|
||||||
local group
|
local group
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
@ -95,49 +100,51 @@ ynh_system_group_exists() {
|
||||||
# ynh_system_user_create --username=discourse --home_dir=/var/www/discourse --use_shell
|
# ynh_system_user_create --username=discourse --home_dir=/var/www/discourse --use_shell
|
||||||
#
|
#
|
||||||
# usage: ynh_system_user_create --username=user_name [--home_dir=home_dir] [--use_shell]
|
# usage: ynh_system_user_create --username=user_name [--home_dir=home_dir] [--use_shell]
|
||||||
# | arg: -u, --username - Name of the system user that will be create
|
# | arg: -u, --username= - Name of the system user that will be create
|
||||||
# | arg: -h, --home_dir - Path of the home dir for the user. Usually the final path of the app. If this argument is omitted, the user will be created without home
|
# | arg: -h, --home_dir= - Path of the home dir for the user. Usually the final path of the app. If this argument is omitted, the user will be created without home
|
||||||
# | arg: -s, --use_shell - Create a user using the default login shell if present. If this argument is omitted, the user will be created with /usr/sbin/nologin shell
|
# | arg: -s, --use_shell - Create a user using the default login shell if present. If this argument is omitted, the user will be created with /usr/sbin/nologin shell
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_system_user_create () {
|
ynh_system_user_create () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=uhs
|
local legacy_args=uhs
|
||||||
declare -Ar args_array=( [u]=username= [h]=home_dir= [s]=use_shell )
|
local -A args_array=( [u]=username= [h]=home_dir= [s]=use_shell )
|
||||||
local username
|
local username
|
||||||
local home_dir
|
local home_dir
|
||||||
local use_shell
|
local use_shell
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
use_shell="${use_shell:-0}"
|
use_shell="${use_shell:-0}"
|
||||||
home_dir="${home_dir:-}"
|
home_dir="${home_dir:-}"
|
||||||
|
|
||||||
if ! ynh_system_user_exists "$username" # Check if the user exists on the system
|
if ! ynh_system_user_exists "$username" # Check if the user exists on the system
|
||||||
then # If the user doesn't exist
|
then # If the user doesn't exist
|
||||||
if [ -n "$home_dir" ]; then # If a home dir is mentioned
|
if [ -n "$home_dir" ]
|
||||||
local user_home_dir="-d $home_dir"
|
then # If a home dir is mentioned
|
||||||
else
|
local user_home_dir="--home-dir $home_dir"
|
||||||
local user_home_dir="--no-create-home"
|
else
|
||||||
fi
|
local user_home_dir="--no-create-home"
|
||||||
if [ $use_shell -eq 1 ]; then # If we want a shell for the user
|
fi
|
||||||
local shell="" # Use default shell
|
if [ $use_shell -eq 1 ]
|
||||||
else
|
then # If we want a shell for the user
|
||||||
local shell="--shell /usr/sbin/nologin"
|
local shell="" # Use default shell
|
||||||
fi
|
else
|
||||||
useradd $user_home_dir --system --user-group $username $shell || ynh_die "Unable to create $username system account"
|
local shell="--shell /usr/sbin/nologin"
|
||||||
fi
|
fi
|
||||||
|
useradd $user_home_dir --system --user-group $username $shell || ynh_die --message="Unable to create $username system account"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Delete a system user
|
# Delete a system user
|
||||||
#
|
#
|
||||||
# usage: ynh_system_user_delete --username=user_name
|
# usage: ynh_system_user_delete --username=user_name
|
||||||
# | arg: -u, --username - Name of the system user that will be create
|
# | arg: -u, --username= - Name of the system user that will be create
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_system_user_delete () {
|
ynh_system_user_delete () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=u
|
local legacy_args=u
|
||||||
declare -Ar args_array=( [u]=username= )
|
local -A args_array=( [u]=username= )
|
||||||
local username
|
local username
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
@ -145,14 +152,14 @@ ynh_system_user_delete () {
|
||||||
# Check if the user exists on the system
|
# Check if the user exists on the system
|
||||||
if ynh_system_user_exists "$username"
|
if ynh_system_user_exists "$username"
|
||||||
then
|
then
|
||||||
deluser $username
|
deluser $username
|
||||||
else
|
else
|
||||||
ynh_print_warn --message="The user $username was not found"
|
ynh_print_warn --message="The user $username was not found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if the group exists on the system
|
# Check if the group exists on the system
|
||||||
if ynh_system_group_exists "$username"
|
if ynh_system_group_exists "$username"
|
||||||
then
|
then
|
||||||
delgroup $username
|
delgroup $username
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,60 +16,26 @@
|
||||||
#
|
#
|
||||||
# It prints a warning to inform that the script was failed, and execute the ynh_clean_setup function if used in the app script
|
# It prints a warning to inform that the script was failed, and execute the ynh_clean_setup function if used in the app script
|
||||||
#
|
#
|
||||||
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_exit_properly () {
|
ynh_exit_properly () {
|
||||||
local exit_code=$?
|
local exit_code=$?
|
||||||
if [ "$exit_code" -eq 0 ]; then
|
if [ "$exit_code" -eq 0 ]; then
|
||||||
exit 0 # Exit without error if the script ended correctly
|
exit 0 # Exit without error if the script ended correctly
|
||||||
fi
|
fi
|
||||||
|
|
||||||
trap '' EXIT # Ignore new exit signals
|
trap '' EXIT # Ignore new exit signals
|
||||||
set +eu # Do not exit anymore if a command fail or if a variable is empty
|
# Do not exit anymore if a command fail or if a variable is empty
|
||||||
|
set +o errexit # set +e
|
||||||
|
set +o nounset # set +u
|
||||||
|
|
||||||
# Small tempo to avoid the next message being mixed up with other DEBUG messages
|
# Small tempo to avoid the next message being mixed up with other DEBUG messages
|
||||||
sleep 0.5
|
sleep 0.5
|
||||||
|
|
||||||
ynh_print_err --message="!!\n $app's script has encountered an error. Its execution was cancelled.\n!!"
|
if type -t ynh_clean_setup > /dev/null; then # Check if the function exist in the app script.
|
||||||
|
ynh_clean_setup # Call the function to do specific cleaning for the app.
|
||||||
|
fi
|
||||||
|
|
||||||
# If the script is executed from the CLI, dump the end of the log that precedes the crash.
|
ynh_die # Exit with error status
|
||||||
if [ "$YNH_INTERFACE" == "cli" ]
|
|
||||||
then
|
|
||||||
# Unset xtrace to not spoil the log
|
|
||||||
set +x
|
|
||||||
|
|
||||||
local ynh_log="/var/log/yunohost/yunohost-cli.log"
|
|
||||||
|
|
||||||
# Wait for the log to be fill with the data until the crash.
|
|
||||||
local timeout=0
|
|
||||||
while ! tail --lines=20 "$ynh_log" | grep --quiet "+ ynh_exit_properly"
|
|
||||||
do
|
|
||||||
((timeout++))
|
|
||||||
if [ $timeout -eq 500 ]; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo -e "\e[34m\e[1mPlease find here an extract of the log before the crash:\e[0m" >&2
|
|
||||||
# Tail the last 30 lines of log of YunoHost
|
|
||||||
# But remove all lines after "ynh_exit_properly"
|
|
||||||
# Remove the timestamp at the beginning of the line
|
|
||||||
# Remove "yunohost.hook..."
|
|
||||||
# Add DEBUG and color it at the beginning of each log line.
|
|
||||||
echo -e "$(tail --lines=30 "$ynh_log" \
|
|
||||||
| sed '1,/+ ynh_exit_properly/!d' \
|
|
||||||
| sed 's/^[[:digit:]: ,-]*//g' \
|
|
||||||
| sed 's/ *yunohost.hook.*\]/ -/g' \
|
|
||||||
| sed 's/^WARNING /&/g' \
|
|
||||||
| sed 's/^DEBUG /& /g' \
|
|
||||||
| sed 's/^INFO /& /g' \
|
|
||||||
| sed 's/^/\\e[34m\\e[1m[DEBUG]\\e[0m: /g')" >&2
|
|
||||||
set -x
|
|
||||||
fi
|
|
||||||
|
|
||||||
if type -t ynh_clean_setup > /dev/null; then # Check if the function exist in the app script.
|
|
||||||
ynh_clean_setup # Call the function to do specific cleaning for the app.
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_die # Exit with error status
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Exits if an error occurs during the execution of the script.
|
# Exits if an error occurs during the execution of the script.
|
||||||
|
@ -83,12 +49,17 @@ ynh_exit_properly () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_abort_if_errors () {
|
ynh_abort_if_errors () {
|
||||||
set -eu # Exit if a command fail, and if a variable is used unset.
|
set -o errexit # set -e; Exit if a command fail
|
||||||
trap ynh_exit_properly EXIT # Capturing exit signals on shell script
|
set -o nounset # set -u; And if a variable is used unset
|
||||||
|
trap ynh_exit_properly EXIT # Capturing exit signals on shell script
|
||||||
}
|
}
|
||||||
|
|
||||||
# Download, check integrity, uncompress and patch the source from app.src
|
# Download, check integrity, uncompress and patch the source from app.src
|
||||||
#
|
#
|
||||||
|
# usage: ynh_setup_source --dest_dir=dest_dir [--source_id=source_id]
|
||||||
|
# | arg: -d, --dest_dir= - Directory where to setup sources
|
||||||
|
# | arg: -s, --source_id= - Name of the app, if the package contains more than one app
|
||||||
|
#
|
||||||
# The file conf/app.src need to contains:
|
# The file conf/app.src need to contains:
|
||||||
#
|
#
|
||||||
# SOURCE_URL=Address to download the app archive
|
# SOURCE_URL=Address to download the app archive
|
||||||
|
@ -127,16 +98,11 @@ ynh_abort_if_errors () {
|
||||||
# Finally, patches named sources/patches/${src_id}-*.patch and extra files in
|
# Finally, patches named sources/patches/${src_id}-*.patch and extra files in
|
||||||
# sources/extra_files/$src_id will be applied to dest_dir
|
# sources/extra_files/$src_id will be applied to dest_dir
|
||||||
#
|
#
|
||||||
#
|
|
||||||
# usage: ynh_setup_source --dest_dir=dest_dir [--source_id=source_id]
|
|
||||||
# | arg: -d, --dest_dir - Directory where to setup sources
|
|
||||||
# | arg: -s, --source_id - Name of the app, if the package contains more than one app
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_setup_source () {
|
ynh_setup_source () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=ds
|
local legacy_args=ds
|
||||||
declare -Ar args_array=( [d]=dest_dir= [s]=source_id= )
|
local -A args_array=( [d]=dest_dir= [s]=source_id= )
|
||||||
local dest_dir
|
local dest_dir
|
||||||
local source_id
|
local source_id
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
|
@ -152,13 +118,13 @@ ynh_setup_source () {
|
||||||
|
|
||||||
# Load value from configuration file (see above for a small doc about this file
|
# Load value from configuration file (see above for a small doc about this file
|
||||||
# format)
|
# format)
|
||||||
local src_url=$(grep 'SOURCE_URL=' "$src_file_path" | cut -d= -f2-)
|
local src_url=$(grep 'SOURCE_URL=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
local src_sum=$(grep 'SOURCE_SUM=' "$src_file_path" | cut -d= -f2-)
|
local src_sum=$(grep 'SOURCE_SUM=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
local src_sumprg=$(grep 'SOURCE_SUM_PRG=' "$src_file_path" | cut -d= -f2-)
|
local src_sumprg=$(grep 'SOURCE_SUM_PRG=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
local src_format=$(grep 'SOURCE_FORMAT=' "$src_file_path" | cut -d= -f2-)
|
local src_format=$(grep 'SOURCE_FORMAT=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
local src_extract=$(grep 'SOURCE_EXTRACT=' "$src_file_path" | cut -d= -f2-)
|
local src_extract=$(grep 'SOURCE_EXTRACT=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
local src_in_subdir=$(grep 'SOURCE_IN_SUBDIR=' "$src_file_path" | cut -d= -f2-)
|
local src_in_subdir=$(grep 'SOURCE_IN_SUBDIR=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
local src_filename=$(grep 'SOURCE_FILENAME=' "$src_file_path" | cut -d= -f2-)
|
local src_filename=$(grep 'SOURCE_FILENAME=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
|
|
||||||
# Default value
|
# Default value
|
||||||
src_sumprg=${src_sumprg:-sha256sum}
|
src_sumprg=${src_sumprg:-sha256sum}
|
||||||
|
@ -166,7 +132,7 @@ ynh_setup_source () {
|
||||||
src_format=${src_format:-tar.gz}
|
src_format=${src_format:-tar.gz}
|
||||||
src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]')
|
src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]')
|
||||||
src_extract=${src_extract:-true}
|
src_extract=${src_extract:-true}
|
||||||
if [ "$src_filename" = "" ] ; then
|
if [ "$src_filename" = "" ]; then
|
||||||
src_filename="${source_id}.${src_format}"
|
src_filename="${source_id}.${src_format}"
|
||||||
fi
|
fi
|
||||||
local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${src_filename}"
|
local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${src_filename}"
|
||||||
|
@ -175,15 +141,15 @@ ynh_setup_source () {
|
||||||
then # Use the local source file if it is present
|
then # Use the local source file if it is present
|
||||||
cp $local_src $src_filename
|
cp $local_src $src_filename
|
||||||
else # If not, download the source
|
else # If not, download the source
|
||||||
local out=`wget -nv -O $src_filename $src_url 2>&1` || ynh_print_err --message="$out"
|
local out=`wget --no-verbose --output-document=$src_filename $src_url 2>&1` || ynh_print_err --message="$out"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check the control sum
|
# Check the control sum
|
||||||
echo "${src_sum} ${src_filename}" | ${src_sumprg} -c --status \
|
echo "${src_sum} ${src_filename}" | ${src_sumprg} --check --status \
|
||||||
|| ynh_die --message="Corrupt source"
|
|| ynh_die --message="Corrupt source"
|
||||||
|
|
||||||
# Extract source into the app dir
|
# Extract source into the app dir
|
||||||
mkdir -p "$dest_dir"
|
mkdir --parents "$dest_dir"
|
||||||
|
|
||||||
if ! "$src_extract"
|
if ! "$src_extract"
|
||||||
then
|
then
|
||||||
|
@ -192,10 +158,11 @@ ynh_setup_source () {
|
||||||
then
|
then
|
||||||
# Zip format
|
# Zip format
|
||||||
# Using of a temp directory, because unzip doesn't manage --strip-components
|
# Using of a temp directory, because unzip doesn't manage --strip-components
|
||||||
if $src_in_subdir ; then
|
if $src_in_subdir
|
||||||
local tmp_dir=$(mktemp -d)
|
then
|
||||||
|
local tmp_dir=$(mktemp --directory)
|
||||||
unzip -quo $src_filename -d "$tmp_dir"
|
unzip -quo $src_filename -d "$tmp_dir"
|
||||||
cp -a $tmp_dir/*/. "$dest_dir"
|
cp --archive $tmp_dir/*/. "$dest_dir"
|
||||||
ynh_secure_remove --file="$tmp_dir"
|
ynh_secure_remove --file="$tmp_dir"
|
||||||
else
|
else
|
||||||
unzip -quo $src_filename -d "$dest_dir"
|
unzip -quo $src_filename -d "$dest_dir"
|
||||||
|
@ -204,40 +171,40 @@ ynh_setup_source () {
|
||||||
local strip=""
|
local strip=""
|
||||||
if [ "$src_in_subdir" != "false" ]
|
if [ "$src_in_subdir" != "false" ]
|
||||||
then
|
then
|
||||||
if [ "$src_in_subdir" == "true" ]; then
|
if [ "$src_in_subdir" == "true" ]
|
||||||
|
then
|
||||||
local sub_dirs=1
|
local sub_dirs=1
|
||||||
else
|
else
|
||||||
local sub_dirs="$src_in_subdir"
|
local sub_dirs="$src_in_subdir"
|
||||||
fi
|
fi
|
||||||
strip="--strip-components $sub_dirs"
|
strip="--strip-components $sub_dirs"
|
||||||
fi
|
fi
|
||||||
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]] ; then
|
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]]
|
||||||
tar -xf $src_filename -C "$dest_dir" $strip
|
then
|
||||||
|
tar --extract --file=$src_filename --directory="$dest_dir" $strip
|
||||||
else
|
else
|
||||||
ynh_die --message="Archive format unrecognized."
|
ynh_die --message="Archive format unrecognized."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Apply patches
|
# Apply patches
|
||||||
if (( $(find $YNH_CWD/../sources/patches/ -type f -name "${source_id}-*.patch" 2> /dev/null | wc -l) > "0" )); then
|
if (( $(find $YNH_CWD/../sources/patches/ -type f -name "${source_id}-*.patch" 2> /dev/null | wc --lines) > "0" ))
|
||||||
local old_dir=$(pwd)
|
then
|
||||||
(cd "$dest_dir" \
|
(cd "$dest_dir"
|
||||||
&& for p in $YNH_CWD/../sources/patches/${source_id}-*.patch; do \
|
for p in $YNH_CWD/../sources/patches/${source_id}-*.patch
|
||||||
patch -p1 < $p; done) \
|
do
|
||||||
|| ynh_die --message="Unable to apply patches"
|
patch --strip=1 < $p
|
||||||
cd $old_dir
|
done) || ynh_die --message="Unable to apply patches"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Add supplementary files
|
# Add supplementary files
|
||||||
if test -e "$YNH_CWD/../sources/extra_files/${source_id}"; then
|
if test -e "$YNH_CWD/../sources/extra_files/${source_id}"; then
|
||||||
cp -a $YNH_CWD/../sources/extra_files/$source_id/. "$dest_dir"
|
cp --archive $YNH_CWD/../sources/extra_files/$source_id/. "$dest_dir"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Curl abstraction to help with POST requests to local pages (such as installation forms)
|
# Curl abstraction to help with POST requests to local pages (such as installation forms)
|
||||||
#
|
#
|
||||||
# $domain and $path_url should be defined externally (and correspond to the domain.tld and the /path (of the app?))
|
|
||||||
#
|
|
||||||
# example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2"
|
# example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2"
|
||||||
#
|
#
|
||||||
# usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ...
|
# usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ...
|
||||||
|
@ -246,6 +213,10 @@ ynh_setup_source () {
|
||||||
# | arg: key2=value2 - (Optionnal) Another POST key and corresponding value
|
# | arg: key2=value2 - (Optionnal) Another POST key and corresponding value
|
||||||
# | arg: ... - (Optionnal) More POST keys and values
|
# | arg: ... - (Optionnal) More POST keys and values
|
||||||
#
|
#
|
||||||
|
# For multiple calls, cookies are persisted between each call for the same app
|
||||||
|
#
|
||||||
|
# $domain and $path_url should be defined externally (and correspond to the domain.tld and the /path (of the app?))
|
||||||
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_local_curl () {
|
ynh_local_curl () {
|
||||||
# Define url of page to curl
|
# Define url of page to curl
|
||||||
|
@ -273,13 +244,20 @@ ynh_local_curl () {
|
||||||
|
|
||||||
# Wait untils nginx has fully reloaded (avoid curl fail with http2)
|
# Wait untils nginx has fully reloaded (avoid curl fail with http2)
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|
||||||
|
local cookiefile=/tmp/ynh-$app-cookie.txt
|
||||||
|
touch $cookiefile
|
||||||
|
chown root $cookiefile
|
||||||
|
chmod 700 $cookiefile
|
||||||
|
|
||||||
# Curl the URL
|
# Curl the URL
|
||||||
curl --silent --show-error -kL -H "Host: $domain" --resolve $domain:443:127.0.0.1 $POST_data "$full_page_url"
|
curl --silent --show-error --insecure --location --header "Host: $domain" --resolve $domain:443:127.0.0.1 $POST_data "$full_page_url" --cookie-jar $cookiefile --cookie $cookiefile
|
||||||
}
|
}
|
||||||
|
|
||||||
# Render templates with Jinja2
|
# Render templates with Jinja2
|
||||||
#
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
# Attention : Variables should be exported before calling this helper to be
|
# Attention : Variables should be exported before calling this helper to be
|
||||||
# accessible inside templates.
|
# accessible inside templates.
|
||||||
#
|
#
|
||||||
|
@ -287,13 +265,13 @@ ynh_local_curl () {
|
||||||
# | arg: some_template - Template file to be rendered
|
# | arg: some_template - Template file to be rendered
|
||||||
# | arg: output_path - The path where the output will be redirected to
|
# | arg: output_path - The path where the output will be redirected to
|
||||||
ynh_render_template() {
|
ynh_render_template() {
|
||||||
local template_path=$1
|
local template_path=$1
|
||||||
local output_path=$2
|
local output_path=$2
|
||||||
mkdir -p "$(dirname $output_path)"
|
mkdir -p "$(dirname $output_path)"
|
||||||
# Taken from https://stackoverflow.com/a/35009576
|
# Taken from https://stackoverflow.com/a/35009576
|
||||||
python2.7 -c 'import os, sys, jinja2; sys.stdout.write(
|
python2.7 -c 'import os, sys, jinja2; sys.stdout.write(
|
||||||
jinja2.Template(sys.stdin.read()
|
jinja2.Template(sys.stdin.read()
|
||||||
).render(os.environ));' < $template_path > $output_path
|
).render(os.environ));' < $template_path > $output_path
|
||||||
}
|
}
|
||||||
|
|
||||||
# Fetch the Debian release codename
|
# Fetch the Debian release codename
|
||||||
|
@ -303,7 +281,7 @@ ynh_render_template() {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
# Requires YunoHost version 2.7.12 or higher.
|
||||||
ynh_get_debian_release () {
|
ynh_get_debian_release () {
|
||||||
echo $(lsb_release --codename --short)
|
echo $(lsb_release --codename --short)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a directory under /tmp
|
# Create a directory under /tmp
|
||||||
|
@ -318,7 +296,7 @@ ynh_mkdir_tmp() {
|
||||||
ynh_print_warn --message="The helper ynh_mkdir_tmp is deprecated."
|
ynh_print_warn --message="The helper ynh_mkdir_tmp is deprecated."
|
||||||
ynh_print_warn --message="You should use 'mktemp -d' instead and manage permissions \
|
ynh_print_warn --message="You should use 'mktemp -d' instead and manage permissions \
|
||||||
properly with chmod/chown."
|
properly with chmod/chown."
|
||||||
local TMP_DIR=$(mktemp -d)
|
local TMP_DIR=$(mktemp --directory)
|
||||||
|
|
||||||
# Give rights to other users could be a security risk.
|
# Give rights to other users could be a security risk.
|
||||||
# But for retrocompatibility we need it. (This helpers is deprecated)
|
# But for retrocompatibility we need it. (This helpers is deprecated)
|
||||||
|
@ -329,13 +307,13 @@ properly with chmod/chown."
|
||||||
# Remove a file or a directory securely
|
# Remove a file or a directory securely
|
||||||
#
|
#
|
||||||
# usage: ynh_secure_remove --file=path_to_remove
|
# usage: ynh_secure_remove --file=path_to_remove
|
||||||
# | arg: -f, --file - File or directory to remove
|
# | arg: -f, --file= - File or directory to remove
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_secure_remove () {
|
ynh_secure_remove () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=f
|
local legacy_args=f
|
||||||
declare -Ar args_array=( [f]=file= )
|
local -A args_array=( [f]=file= )
|
||||||
local file
|
local file
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
@ -349,26 +327,29 @@ ynh_secure_remove () {
|
||||||
ynh_print_warn --message="/!\ Packager ! You provided more than one argument to ynh_secure_remove but it will be ignored... Use this helper with one argument at time."
|
ynh_print_warn --message="/!\ Packager ! You provided more than one argument to ynh_secure_remove but it will be ignored... Use this helper with one argument at time."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$forbidden_path" =~ "$file" \
|
if [[ -z "$file" ]]
|
||||||
|
then
|
||||||
|
ynh_print_warn --message="ynh_secure_remove called with empty argument, ignoring."
|
||||||
|
elif [[ "$forbidden_path" =~ "$file" \
|
||||||
# Match all paths or subpaths in $forbidden_path
|
# Match all paths or subpaths in $forbidden_path
|
||||||
|| "$file" =~ ^/[[:alnum:]]+$ \
|
|| "$file" =~ ^/[[:alnum:]]+$ \
|
||||||
# Match all first level paths from / (Like /var, /root, etc...)
|
# Match all first level paths from / (Like /var, /root, etc...)
|
||||||
|| "${file:${#file}-1}" = "/" ]]
|
|| "${file:${#file}-1}" = "/" ]]
|
||||||
# Match if the path finishes by /. Because it seems there is an empty variable
|
# Match if the path finishes by /. Because it seems there is an empty variable
|
||||||
then
|
then
|
||||||
ynh_print_warn --message="Avoid deleting $file."
|
ynh_print_warn --message="Not deleting '$file' because it is not an acceptable path to delete."
|
||||||
|
elif [ -e "$file" ]
|
||||||
|
then
|
||||||
|
rm --recursive "$file"
|
||||||
else
|
else
|
||||||
if [ -e "$file" ]
|
ynh_print_info --message="'$file' wasn't deleted because it doesn't exist."
|
||||||
then
|
|
||||||
sudo rm -R "$file"
|
|
||||||
else
|
|
||||||
ynh_print_info --message="$file wasn't deleted because it doesn't exist."
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Extract a key from a plain command output
|
# Extract a key from a plain command output
|
||||||
#
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
# example: yunohost user info tata --output-as plain | ynh_get_plain_key mail
|
# example: yunohost user info tata --output-as plain | ynh_get_plain_key mail
|
||||||
#
|
#
|
||||||
# usage: ynh_get_plain_key key [subkey [subsubkey ...]]
|
# usage: ynh_get_plain_key key [subkey [subsubkey ...]]
|
||||||
|
@ -382,12 +363,16 @@ ynh_get_plain_key() {
|
||||||
# an info to be redacted by the core
|
# an info to be redacted by the core
|
||||||
local key_=$1
|
local key_=$1
|
||||||
shift
|
shift
|
||||||
while read line; do
|
while read line
|
||||||
if [[ "$founded" == "1" ]] ; then
|
do
|
||||||
|
if [[ "$founded" == "1" ]]
|
||||||
|
then
|
||||||
[[ "$line" =~ ^${prefix}[^#] ]] && return
|
[[ "$line" =~ ^${prefix}[^#] ]] && return
|
||||||
echo $line
|
echo $line
|
||||||
elif [[ "$line" =~ ^${prefix}${key_}$ ]]; then
|
elif [[ "$line" =~ ^${prefix}${key_}$ ]]
|
||||||
if [[ -n "${1:-}" ]]; then
|
then
|
||||||
|
if [[ -n "${1:-}" ]]
|
||||||
|
then
|
||||||
prefix+="#"
|
prefix+="#"
|
||||||
key_=$1
|
key_=$1
|
||||||
shift
|
shift
|
||||||
|
@ -400,72 +385,75 @@ ynh_get_plain_key() {
|
||||||
|
|
||||||
# Read the value of a key in a ynh manifest file
|
# Read the value of a key in a ynh manifest file
|
||||||
#
|
#
|
||||||
# usage: ynh_read_manifest manifest key
|
# usage: ynh_read_manifest --manifest="manifest.json" --key="key"
|
||||||
# | arg: -m, --manifest= - Path of the manifest to read
|
# | arg: -m, --manifest= - Path of the manifest to read
|
||||||
# | arg: -k, --key= - Name of the key to find
|
# | arg: -k, --key= - Name of the key to find
|
||||||
|
# | ret: the value associate to that key
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_read_manifest () {
|
ynh_read_manifest () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=mk
|
local legacy_args=mk
|
||||||
declare -Ar args_array=( [m]=manifest= [k]=manifest_key= )
|
local -A args_array=( [m]=manifest= [k]=manifest_key= )
|
||||||
local manifest
|
local manifest
|
||||||
local manifest_key
|
local manifest_key
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
if [ ! -e "$manifest" ]; then
|
if [ ! -e "$manifest" ]; then
|
||||||
# If the manifest isn't found, try the common place for backup and restore script.
|
# If the manifest isn't found, try the common place for backup and restore script.
|
||||||
manifest="../settings/manifest.json"
|
manifest="../settings/manifest.json"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
jq ".$manifest_key" "$manifest" --raw-output
|
jq ".$manifest_key" "$manifest" --raw-output
|
||||||
}
|
}
|
||||||
|
|
||||||
# Read the upstream version from the manifest
|
# Read the upstream version from the manifest
|
||||||
#
|
#
|
||||||
|
# usage: ynh_app_upstream_version [--manifest="manifest.json"]
|
||||||
|
# | arg: -m, --manifest= - Path of the manifest to read
|
||||||
|
# | ret: the version number of the upstream app
|
||||||
|
#
|
||||||
# The version number in the manifest is defined by <upstreamversion>~ynh<packageversion>
|
# The version number in the manifest is defined by <upstreamversion>~ynh<packageversion>
|
||||||
# For example : 4.3-2~ynh3
|
# For example : 4.3-2~ynh3
|
||||||
# This include the number before ~ynh
|
# This include the number before ~ynh
|
||||||
# In the last example it return 4.3-2
|
# In the last example it return 4.3-2
|
||||||
#
|
#
|
||||||
# usage: ynh_app_upstream_version [-m manifest]
|
|
||||||
# | arg: -m, --manifest= - Path of the manifest to read
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_app_upstream_version () {
|
ynh_app_upstream_version () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=m
|
local legacy_args=m
|
||||||
declare -Ar args_array=( [m]=manifest= )
|
local -A args_array=( [m]=manifest= )
|
||||||
local manifest
|
local manifest
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
manifest="${manifest:-../manifest.json}"
|
manifest="${manifest:-../manifest.json}"
|
||||||
|
|
||||||
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
||||||
echo "${version_key/~ynh*/}"
|
echo "${version_key/~ynh*/}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Read package version from the manifest
|
# Read package version from the manifest
|
||||||
#
|
#
|
||||||
|
# usage: ynh_app_package_version [--manifest="manifest.json"]
|
||||||
|
# | arg: -m, --manifest= - Path of the manifest to read
|
||||||
|
# | ret: the version number of the package
|
||||||
|
#
|
||||||
# The version number in the manifest is defined by <upstreamversion>~ynh<packageversion>
|
# The version number in the manifest is defined by <upstreamversion>~ynh<packageversion>
|
||||||
# For example : 4.3-2~ynh3
|
# For example : 4.3-2~ynh3
|
||||||
# This include the number after ~ynh
|
# This include the number after ~ynh
|
||||||
# In the last example it return 3
|
# In the last example it return 3
|
||||||
#
|
#
|
||||||
# usage: ynh_app_package_version [-m manifest]
|
|
||||||
# | arg: -m, --manifest= - Path of the manifest to read
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_app_package_version () {
|
ynh_app_package_version () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=m
|
local legacy_args=m
|
||||||
declare -Ar args_array=( [m]=manifest= )
|
local -A args_array=( [m]=manifest= )
|
||||||
local manifest
|
local manifest
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
manifest="${manifest:-../manifest.json}"
|
manifest="${manifest:-../manifest.json}"
|
||||||
|
|
||||||
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
||||||
echo "${version_key/*~ynh/}"
|
echo "${version_key/*~ynh/}"
|
||||||
}
|
}
|
||||||
|
@ -488,32 +476,34 @@ ynh_app_package_version () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
# Requires YunoHost version 3.5.0 or higher.
|
||||||
ynh_check_app_version_changed () {
|
ynh_check_app_version_changed () {
|
||||||
local force_upgrade=${YNH_FORCE_UPGRADE:-0}
|
local force_upgrade=${YNH_FORCE_UPGRADE:-0}
|
||||||
local package_check=${PACKAGE_CHECK_EXEC:-0}
|
local package_check=${PACKAGE_CHECK_EXEC:-0}
|
||||||
|
|
||||||
# By default, upstream app version has changed
|
# By default, upstream app version has changed
|
||||||
local return_value="UPGRADE_APP"
|
local return_value="UPGRADE_APP"
|
||||||
|
|
||||||
local current_version=$(ynh_read_manifest --manifest="/etc/yunohost/apps/$YNH_APP_INSTANCE_NAME/manifest.json" --manifest_key="version" || echo 1.0)
|
local current_version=$(ynh_read_manifest --manifest="/etc/yunohost/apps/$YNH_APP_INSTANCE_NAME/manifest.json" --manifest_key="version" || echo 1.0)
|
||||||
local current_upstream_version="$(ynh_app_upstream_version --manifest="/etc/yunohost/apps/$YNH_APP_INSTANCE_NAME/manifest.json")"
|
local current_upstream_version="$(ynh_app_upstream_version --manifest="/etc/yunohost/apps/$YNH_APP_INSTANCE_NAME/manifest.json")"
|
||||||
local update_version=$(ynh_read_manifest --manifest="../manifest.json" --manifest_key="version" || echo 1.0)
|
local update_version=$(ynh_read_manifest --manifest="../manifest.json" --manifest_key="version" || echo 1.0)
|
||||||
local update_upstream_version="$(ynh_app_upstream_version)"
|
local update_upstream_version="$(ynh_app_upstream_version)"
|
||||||
|
|
||||||
if [ "$current_version" == "$update_version" ] ; then
|
if [ "$current_version" == "$update_version" ]
|
||||||
# Complete versions are the same
|
then
|
||||||
if [ "$force_upgrade" != "0" ]
|
# Complete versions are the same
|
||||||
then
|
if [ "$force_upgrade" != "0" ]
|
||||||
ynh_print_info --message="Upgrade forced by YNH_FORCE_UPGRADE."
|
then
|
||||||
unset YNH_FORCE_UPGRADE
|
ynh_print_info --message="Upgrade forced by YNH_FORCE_UPGRADE."
|
||||||
elif [ "$package_check" != "0" ]
|
unset YNH_FORCE_UPGRADE
|
||||||
then
|
elif [ "$package_check" != "0" ]
|
||||||
ynh_print_info --message="Upgrade forced for package check."
|
then
|
||||||
else
|
ynh_print_info --message="Upgrade forced for package check."
|
||||||
ynh_die "Up-to-date, nothing to do" 0
|
else
|
||||||
fi
|
ynh_die "Up-to-date, nothing to do" 0
|
||||||
elif [ "$current_upstream_version" == "$update_upstream_version" ] ; then
|
fi
|
||||||
# Upstream versions are the same, only YunoHost package versions differ
|
elif [ "$current_upstream_version" == "$update_upstream_version" ]
|
||||||
return_value="UPGRADE_PACKAGE"
|
then
|
||||||
fi
|
# Upstream versions are the same, only YunoHost package versions differ
|
||||||
echo $return_value
|
return_value="UPGRADE_PACKAGE"
|
||||||
|
fi
|
||||||
|
echo $return_value
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ backup_dir="${1}/conf/ldap"
|
||||||
|
|
||||||
# Backup the configuration
|
# Backup the configuration
|
||||||
ynh_backup "/etc/ldap/slapd.conf" "${backup_dir}/slapd.conf"
|
ynh_backup "/etc/ldap/slapd.conf" "${backup_dir}/slapd.conf"
|
||||||
sudo slapcat -b cn=config -l "${backup_dir}/cn=config.master.ldif"
|
slapcat -b cn=config -l "${backup_dir}/cn=config.master.ldif"
|
||||||
|
|
||||||
# Backup the database
|
# Backup the database
|
||||||
sudo slapcat -b dc=yunohost,dc=org -l "${backup_dir}/dc=yunohost-dc=org.ldif"
|
slapcat -b dc=yunohost,dc=org -l "${backup_dir}/dc=yunohost-dc=org.ldif"
|
||||||
|
|
|
@ -38,28 +38,35 @@ do_pre_regen() {
|
||||||
if [[ -f $services_path ]]; then
|
if [[ -f $services_path ]]; then
|
||||||
tmp_services_path="${services_path}-tmp"
|
tmp_services_path="${services_path}-tmp"
|
||||||
new_services_path="${services_path}-new"
|
new_services_path="${services_path}-new"
|
||||||
sudo cp "$services_path" "$tmp_services_path"
|
cp "$services_path" "$tmp_services_path"
|
||||||
_update_services "$new_services_path" || {
|
_update_services "$new_services_path" || {
|
||||||
sudo mv "$tmp_services_path" "$services_path"
|
mv "$tmp_services_path" "$services_path"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
if [[ -f $new_services_path ]]; then
|
if [[ -f $new_services_path ]]; then
|
||||||
# replace services.yml with new one
|
# replace services.yml with new one
|
||||||
sudo mv "$new_services_path" "$services_path"
|
mv "$new_services_path" "$services_path"
|
||||||
sudo mv "$tmp_services_path" "${services_path}-old"
|
mv "$tmp_services_path" "${services_path}-old"
|
||||||
else
|
else
|
||||||
sudo rm -f "$tmp_services_path"
|
rm -f "$tmp_services_path"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
sudo cp services.yml /etc/yunohost/services.yml
|
cp services.yml /etc/yunohost/services.yml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "$pending_dir"/etc/etckeeper/
|
# add cron job for diagnosis to be ran at 7h and 19h + a random delay between
|
||||||
cp etckeeper.conf "$pending_dir"/etc/etckeeper/
|
# 0 and 10min, meant to avoid every instances running their diagnosis at
|
||||||
|
# exactly the same time, which may overload the diagnosis server.
|
||||||
|
mkdir -p $pending_dir/etc/cron.d/
|
||||||
|
cat > $pending_dir/etc/cron.d/yunohost-diagnosis << EOF
|
||||||
|
SHELL=/bin/bash
|
||||||
|
0 7,19 * * * root : YunoHost Diagnosis; sleep \$((RANDOM\\%600)); yunohost diagnosis run > /dev/null
|
||||||
|
EOF
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_update_services() {
|
_update_services() {
|
||||||
sudo python2 - << EOF
|
python2 - << EOF
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,6 +111,12 @@ for service, conf in new_services.items():
|
||||||
if conffiles:
|
if conffiles:
|
||||||
services[service]['conffiles'] = conffiles
|
services[service]['conffiles'] = conffiles
|
||||||
|
|
||||||
|
# Remove legacy /var/log/daemon.log and /var/log/syslog from log entries
|
||||||
|
# because they are too general. Instead, now the journalctl log is
|
||||||
|
# returned by default which is more relevant.
|
||||||
|
if "log" in services[service]:
|
||||||
|
if services[service]["log"] in ["/var/log/syslog", "/var/log/daemon.log"]:
|
||||||
|
del services[service]["log"]
|
||||||
|
|
||||||
if updated:
|
if updated:
|
||||||
with open('/etc/yunohost/services.yml-new', 'w') as f:
|
with open('/etc/yunohost/services.yml-new', 'w') as f:
|
||||||
|
|
|
@ -99,13 +99,13 @@ do_post_regen() {
|
||||||
[[ -f "${index_txt}" ]] || {
|
[[ -f "${index_txt}" ]] || {
|
||||||
if [[ -f "${index_txt}.saved" ]]; then
|
if [[ -f "${index_txt}.saved" ]]; then
|
||||||
# use saved database from 2.2
|
# use saved database from 2.2
|
||||||
sudo cp "${index_txt}.saved" "${index_txt}"
|
cp "${index_txt}.saved" "${index_txt}"
|
||||||
elif [[ -f "${index_txt}.old" ]]; then
|
elif [[ -f "${index_txt}.old" ]]; then
|
||||||
# ... or use the state-1 database
|
# ... or use the state-1 database
|
||||||
sudo cp "${index_txt}.old" "${index_txt}"
|
cp "${index_txt}.old" "${index_txt}"
|
||||||
else
|
else
|
||||||
# ... or create an empty one
|
# ... or create an empty one
|
||||||
sudo touch "${index_txt}"
|
touch "${index_txt}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,9 @@ do_pre_regen() {
|
||||||
cp -a ldap.conf slapd.conf "$ldap_dir"
|
cp -a ldap.conf slapd.conf "$ldap_dir"
|
||||||
cp -a sudo.schema mailserver.schema yunohost.schema "$schema_dir"
|
cp -a sudo.schema mailserver.schema yunohost.schema "$schema_dir"
|
||||||
|
|
||||||
|
mkdir -p ${pending_dir}/etc/systemd/system/slapd.service.d/
|
||||||
|
cp systemd-override.conf ${pending_dir}/etc/systemd/system/slapd.service.d/ynh-override.conf
|
||||||
|
|
||||||
install -D -m 644 slapd.default "${pending_dir}/etc/default/slapd"
|
install -D -m 644 slapd.default "${pending_dir}/etc/default/slapd"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +84,14 @@ do_post_regen() {
|
||||||
chown -R openldap:openldap /etc/ldap/slapd.d/
|
chown -R openldap:openldap /etc/ldap/slapd.d/
|
||||||
chown -R root:ssl-cert /etc/yunohost/certs/yunohost.org/
|
chown -R root:ssl-cert /etc/yunohost/certs/yunohost.org/
|
||||||
chmod o-rwx /etc/yunohost/certs/yunohost.org/
|
chmod o-rwx /etc/yunohost/certs/yunohost.org/
|
||||||
|
chmod -R g+rx /etc/yunohost/certs/yunohost.org/
|
||||||
|
|
||||||
|
# If we changed the systemd ynh-override conf
|
||||||
|
if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/slapd.service.d/ynh-override.conf$"
|
||||||
|
then
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl restart slapd
|
||||||
|
fi
|
||||||
|
|
||||||
[ -z "$regen_conf_files" ] && exit 0
|
[ -z "$regen_conf_files" ] && exit 0
|
||||||
|
|
||||||
|
@ -126,7 +137,7 @@ do_post_regen() {
|
||||||
# wait a maximum time of 5 minutes
|
# wait a maximum time of 5 minutes
|
||||||
# yes, force-reload behave like a restart
|
# yes, force-reload behave like a restart
|
||||||
number_of_wait=0
|
number_of_wait=0
|
||||||
while ! sudo su admin -c '' && ((number_of_wait < 60))
|
while ! su admin -c '' && ((number_of_wait < 60))
|
||||||
do
|
do
|
||||||
sleep 5
|
sleep 5
|
||||||
((number_of_wait += 1))
|
((number_of_wait += 1))
|
||||||
|
|
|
@ -14,7 +14,7 @@ do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
[[ -z "$regen_conf_files" ]] \
|
||||||
|| sudo service nslcd restart
|
|| service nslcd restart
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -14,7 +14,7 @@ do_pre_regen() {
|
||||||
|
|
||||||
# retrieve variables
|
# retrieve variables
|
||||||
main_domain=$(cat /etc/yunohost/current_host)
|
main_domain=$(cat /etc/yunohost/current_host)
|
||||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
domain_list=$(yunohost domain list --output-as plain --quiet)
|
||||||
|
|
||||||
# install main conf file
|
# install main conf file
|
||||||
cat metronome.cfg.lua \
|
cat metronome.cfg.lua \
|
||||||
|
@ -41,20 +41,25 @@ do_pre_regen() {
|
||||||
do_post_regen() {
|
do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
# fix some permissions
|
|
||||||
sudo chown -R metronome: /var/lib/metronome/
|
|
||||||
sudo chown -R metronome: /etc/metronome/conf.d/
|
|
||||||
|
|
||||||
# retrieve variables
|
# retrieve variables
|
||||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
main_domain=$(cat /etc/yunohost/current_host)
|
||||||
|
domain_list=$(yunohost domain list --exclude-subdomains --output-as plain --quiet)
|
||||||
|
|
||||||
# create metronome directories for domains
|
# create metronome directories for domains
|
||||||
for domain in $domain_list; do
|
for domain in $domain_list; do
|
||||||
sudo mkdir -p "/var/lib/metronome/${domain//./%2e}/pep"
|
mkdir -p "/var/lib/metronome/${domain//./%2e}/pep"
|
||||||
|
# http_upload directory must be writable by metronome and readable by nginx
|
||||||
|
mkdir -p "/var/xmpp-upload/${domain}/upload"
|
||||||
|
chmod g+s "/var/xmpp-upload/${domain}/upload"
|
||||||
|
chown -R metronome:www-data "/var/xmpp-upload/${domain}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# fix some permissions
|
||||||
|
chown -R metronome: /var/lib/metronome/
|
||||||
|
chown -R metronome: /etc/metronome/conf.d/
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
[[ -z "$regen_conf_files" ]] \
|
||||||
|| sudo service metronome restart
|
|| service metronome restart
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -23,10 +23,12 @@ do_init_regen() {
|
||||||
rm -f "${nginx_dir}/sites-enabled/default"
|
rm -f "${nginx_dir}/sites-enabled/default"
|
||||||
|
|
||||||
export compatibility="intermediate"
|
export compatibility="intermediate"
|
||||||
|
ynh_render_template "security.conf.inc" "${nginx_conf_dir}/security.conf.inc"
|
||||||
ynh_render_template "yunohost_admin.conf" "${nginx_conf_dir}/yunohost_admin.conf"
|
ynh_render_template "yunohost_admin.conf" "${nginx_conf_dir}/yunohost_admin.conf"
|
||||||
|
|
||||||
# Restart nginx if conf looks good, otherwise display error and exit unhappy
|
# Restart nginx if conf looks good, otherwise display error and exit unhappy
|
||||||
nginx -t 2>/dev/null && service nginx restart || (nginx -t && exit 1)
|
nginx -t 2>/dev/null || { nginx -t; exit 1; }
|
||||||
|
systemctl restart nginx || { journalctl --no-pager --lines=10 -u nginx >&2; exit 1; }
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
@ -45,10 +47,11 @@ do_pre_regen() {
|
||||||
|
|
||||||
# retrieve variables
|
# retrieve variables
|
||||||
main_domain=$(cat /etc/yunohost/current_host)
|
main_domain=$(cat /etc/yunohost/current_host)
|
||||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
domain_list=$(yunohost domain list --output-as plain --quiet)
|
||||||
|
|
||||||
# Support different strategy for security configurations
|
# Support different strategy for security configurations
|
||||||
export compatibility="$(yunohost settings get 'security.nginx.compatibility')"
|
export compatibility="$(yunohost settings get 'security.nginx.compatibility')"
|
||||||
|
ynh_render_template "security.conf.inc" "${nginx_conf_dir}/security.conf.inc"
|
||||||
|
|
||||||
# add domain conf files
|
# add domain conf files
|
||||||
for domain in $domain_list; do
|
for domain in $domain_list; do
|
||||||
|
@ -102,15 +105,30 @@ do_post_regen() {
|
||||||
[ -z "$regen_conf_files" ] && exit 0
|
[ -z "$regen_conf_files" ] && exit 0
|
||||||
|
|
||||||
# retrieve variables
|
# retrieve variables
|
||||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
domain_list=$(yunohost domain list --output-as plain --quiet)
|
||||||
|
|
||||||
# create NGINX conf directories for domains
|
# create NGINX conf directories for domains
|
||||||
for domain in $domain_list; do
|
for domain in $domain_list; do
|
||||||
sudo mkdir -p "/etc/nginx/conf.d/${domain}.d"
|
mkdir -p "/etc/nginx/conf.d/${domain}.d"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Reload nginx configuration
|
# Get rid of legacy lets encrypt snippets
|
||||||
pgrep nginx && sudo service nginx reload
|
for domain in $domain_list; do
|
||||||
|
# If the legacy letsencrypt / acme-challenge domain-specific snippet is still there
|
||||||
|
if [ -e /etc/nginx/conf.d/${domain}.d/000-acmechallenge.conf ]
|
||||||
|
then
|
||||||
|
# And if we're effectively including the new domain-independant snippet now
|
||||||
|
if grep -q "include /etc/nginx/conf.d/acme-challenge.conf.inc;" /etc/nginx/conf.d/${domain}.conf
|
||||||
|
then
|
||||||
|
# Delete the old domain-specific snippet
|
||||||
|
rm /etc/nginx/conf.d/${domain}.d/000-acmechallenge.conf
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Reload nginx if conf looks good, otherwise display error and exit unhappy
|
||||||
|
nginx -t 2>/dev/null || { nginx -t; exit 1; }
|
||||||
|
pgrep nginx && systemctl reload nginx || { journalctl --no-pager --lines=10 -u nginx >&2; exit 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -20,7 +20,7 @@ do_pre_regen() {
|
||||||
|
|
||||||
# prepare main.cf conf file
|
# prepare main.cf conf file
|
||||||
main_domain=$(cat /etc/yunohost/current_host)
|
main_domain=$(cat /etc/yunohost/current_host)
|
||||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet | tr '\n' ' ')
|
domain_list=$(yunohost domain list --output-as plain --quiet | tr '\n' ' ')
|
||||||
|
|
||||||
# Support different strategy for security configurations
|
# Support different strategy for security configurations
|
||||||
export compatibility="$(yunohost settings get 'security.postfix.compatibility')"
|
export compatibility="$(yunohost settings get 'security.postfix.compatibility')"
|
||||||
|
@ -35,7 +35,8 @@ do_pre_regen() {
|
||||||
> "${default_dir}/postsrsd"
|
> "${default_dir}/postsrsd"
|
||||||
|
|
||||||
# adapt it for IPv4-only hosts
|
# adapt it for IPv4-only hosts
|
||||||
if [ ! -f /proc/net/if_inet6 ]; then
|
ipv6="$(yunohost settings get 'smtp.allow_ipv6')"
|
||||||
|
if [ "$ipv6" == "False" ] || [ ! -f /proc/net/if_inet6 ]; then
|
||||||
sed -i \
|
sed -i \
|
||||||
's/ \[::ffff:127.0.0.0\]\/104 \[::1\]\/128//g' \
|
's/ \[::ffff:127.0.0.0\]\/104 \[::1\]\/128//g' \
|
||||||
"${postfix_dir}/main.cf"
|
"${postfix_dir}/main.cf"
|
||||||
|
@ -49,7 +50,7 @@ do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
[[ -z "$regen_conf_files" ]] \
|
||||||
|| { sudo service postfix restart && sudo service postsrsd restart; }
|
|| { service postfix restart && service postsrsd restart; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
. /usr/share/yunohost/helpers
|
||||||
|
|
||||||
do_pre_regen() {
|
do_pre_regen() {
|
||||||
pending_dir=$1
|
pending_dir=$1
|
||||||
|
|
||||||
|
@ -14,11 +16,10 @@ do_pre_regen() {
|
||||||
cp dovecot-ldap.conf "${dovecot_dir}/dovecot-ldap.conf"
|
cp dovecot-ldap.conf "${dovecot_dir}/dovecot-ldap.conf"
|
||||||
cp dovecot.sieve "${dovecot_dir}/global_script/dovecot.sieve"
|
cp dovecot.sieve "${dovecot_dir}/global_script/dovecot.sieve"
|
||||||
|
|
||||||
# prepare dovecot.conf conf file
|
export pop3_enabled="$(yunohost settings get 'pop3.enabled')"
|
||||||
main_domain=$(cat /etc/yunohost/current_host)
|
export main_domain=$(cat /etc/yunohost/current_host)
|
||||||
cat dovecot.conf \
|
|
||||||
| sed "s/{{ main_domain }}/${main_domain}/g" \
|
ynh_render_template "dovecot.conf" "${dovecot_dir}/dovecot.conf"
|
||||||
> "${dovecot_dir}/dovecot.conf"
|
|
||||||
|
|
||||||
# adapt it for IPv4-only hosts
|
# adapt it for IPv4-only hosts
|
||||||
if [ ! -f /proc/net/if_inet6 ]; then
|
if [ ! -f /proc/net/if_inet6 ]; then
|
||||||
|
@ -35,28 +36,28 @@ do_pre_regen() {
|
||||||
do_post_regen() {
|
do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
sudo mkdir -p "/etc/dovecot/yunohost.d/pre-ext.d"
|
mkdir -p "/etc/dovecot/yunohost.d/pre-ext.d"
|
||||||
sudo mkdir -p "/etc/dovecot/yunohost.d/post-ext.d"
|
mkdir -p "/etc/dovecot/yunohost.d/post-ext.d"
|
||||||
|
|
||||||
# create vmail user
|
# create vmail user
|
||||||
id vmail > /dev/null 2>&1 \
|
id vmail > /dev/null 2>&1 \
|
||||||
|| sudo adduser --system --ingroup mail --uid 500 vmail
|
|| adduser --system --ingroup mail --uid 500 vmail
|
||||||
|
|
||||||
# fix permissions
|
# fix permissions
|
||||||
sudo chown -R vmail:mail /etc/dovecot/global_script
|
chown -R vmail:mail /etc/dovecot/global_script
|
||||||
sudo chmod 770 /etc/dovecot/global_script
|
chmod 770 /etc/dovecot/global_script
|
||||||
sudo chown root:mail /var/mail
|
chown root:mail /var/mail
|
||||||
sudo chmod 1775 /var/mail
|
chmod 1775 /var/mail
|
||||||
|
|
||||||
[ -z "$regen_conf_files" ] && exit 0
|
[ -z "$regen_conf_files" ] && exit 0
|
||||||
|
|
||||||
# compile sieve script
|
# compile sieve script
|
||||||
[[ "$regen_conf_files" =~ dovecot\.sieve ]] && {
|
[[ "$regen_conf_files" =~ dovecot\.sieve ]] && {
|
||||||
sudo sievec /etc/dovecot/global_script/dovecot.sieve
|
sievec /etc/dovecot/global_script/dovecot.sieve
|
||||||
sudo chown -R vmail:mail /etc/dovecot/global_script
|
chown -R vmail:mail /etc/dovecot/global_script
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo service dovecot restart
|
service dovecot restart
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -22,11 +22,11 @@ do_post_regen() {
|
||||||
##
|
##
|
||||||
|
|
||||||
# create DKIM directory with proper permission
|
# create DKIM directory with proper permission
|
||||||
sudo mkdir -p /etc/dkim
|
mkdir -p /etc/dkim
|
||||||
sudo chown _rspamd /etc/dkim
|
chown _rspamd /etc/dkim
|
||||||
|
|
||||||
# retrieve domain list
|
# retrieve domain list
|
||||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
domain_list=$(yunohost domain list --output-as plain --quiet)
|
||||||
|
|
||||||
# create DKIM key for domains
|
# create DKIM key for domains
|
||||||
for domain in $domain_list; do
|
for domain in $domain_list; do
|
||||||
|
@ -34,30 +34,30 @@ do_post_regen() {
|
||||||
[ ! -f "$domain_key" ] && {
|
[ ! -f "$domain_key" ] && {
|
||||||
# We use a 1024 bit size because nsupdate doesn't seem to be able to
|
# We use a 1024 bit size because nsupdate doesn't seem to be able to
|
||||||
# handle 2048...
|
# handle 2048...
|
||||||
sudo opendkim-genkey --domain="$domain" \
|
opendkim-genkey --domain="$domain" \
|
||||||
--selector=mail --directory=/etc/dkim -b 1024
|
--selector=mail --directory=/etc/dkim -b 1024
|
||||||
sudo mv /etc/dkim/mail.private "$domain_key"
|
mv /etc/dkim/mail.private "$domain_key"
|
||||||
sudo mv /etc/dkim/mail.txt "/etc/dkim/${domain}.mail.txt"
|
mv /etc/dkim/mail.txt "/etc/dkim/${domain}.mail.txt"
|
||||||
}
|
}
|
||||||
done
|
done
|
||||||
|
|
||||||
# fix DKIM keys permissions
|
# fix DKIM keys permissions
|
||||||
sudo chown _rspamd /etc/dkim/*.mail.key
|
chown _rspamd /etc/dkim/*.mail.key
|
||||||
sudo chmod 400 /etc/dkim/*.mail.key
|
chmod 400 /etc/dkim/*.mail.key
|
||||||
|
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
[ -z "$regen_conf_files" ] && exit 0
|
[ -z "$regen_conf_files" ] && exit 0
|
||||||
|
|
||||||
# compile sieve script
|
# compile sieve script
|
||||||
[[ "$regen_conf_files" =~ rspamd\.sieve ]] && {
|
[[ "$regen_conf_files" =~ rspamd\.sieve ]] && {
|
||||||
sudo sievec /etc/dovecot/global_script/rspamd.sieve
|
sievec /etc/dovecot/global_script/rspamd.sieve
|
||||||
sudo chown -R vmail:mail /etc/dovecot/global_script
|
chown -R vmail:mail /etc/dovecot/global_script
|
||||||
sudo systemctl restart dovecot
|
systemctl restart dovecot
|
||||||
}
|
}
|
||||||
|
|
||||||
# Restart rspamd due to the upgrade
|
# Restart rspamd due to the upgrade
|
||||||
# https://rspamd.com/announce/2016/08/01/rspamd-1.3.1.html
|
# https://rspamd.com/announce/2016/08/01/rspamd-1.3.1.html
|
||||||
sudo systemctl -q restart rspamd.service
|
systemctl -q restart rspamd.service
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -18,12 +18,12 @@ do_post_regen() {
|
||||||
if [ ! -f /etc/yunohost/mysql ]; then
|
if [ ! -f /etc/yunohost/mysql ]; then
|
||||||
|
|
||||||
# ensure that mysql is running
|
# ensure that mysql is running
|
||||||
sudo systemctl -q is-active mysql.service \
|
systemctl -q is-active mysql.service \
|
||||||
|| sudo service mysql start
|
|| service mysql start
|
||||||
|
|
||||||
# generate and set new root password
|
# generate and set new root password
|
||||||
mysql_password=$(ynh_string_random 10)
|
mysql_password=$(ynh_string_random 10)
|
||||||
sudo mysqladmin -s -u root -pyunohost password "$mysql_password" || {
|
mysqladmin -s -u root -pyunohost password "$mysql_password" || {
|
||||||
if [ $FORCE -eq 1 ]; then
|
if [ $FORCE -eq 1 ]; then
|
||||||
echo "It seems that you have already configured MySQL." \
|
echo "It seems that you have already configured MySQL." \
|
||||||
"YunoHost needs to have a root access to MySQL to runs its" \
|
"YunoHost needs to have a root access to MySQL to runs its" \
|
||||||
|
@ -31,13 +31,13 @@ do_post_regen() {
|
||||||
"You can find this new password in /etc/yunohost/mysql." >&2
|
"You can find this new password in /etc/yunohost/mysql." >&2
|
||||||
|
|
||||||
# set new password with debconf
|
# set new password with debconf
|
||||||
sudo debconf-set-selections << EOF
|
debconf-set-selections << EOF
|
||||||
$MYSQL_PKG mysql-server/root_password password $mysql_password
|
$MYSQL_PKG mysql-server/root_password password $mysql_password
|
||||||
$MYSQL_PKG mysql-server/root_password_again password $mysql_password
|
$MYSQL_PKG mysql-server/root_password_again password $mysql_password
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# reconfigure Debian package
|
# reconfigure Debian package
|
||||||
sudo dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1
|
dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1
|
||||||
else
|
else
|
||||||
echo "It seems that you have already configured MySQL." \
|
echo "It seems that you have already configured MySQL." \
|
||||||
"YunoHost needs to have a root access to MySQL to runs its" \
|
"YunoHost needs to have a root access to MySQL to runs its" \
|
||||||
|
@ -49,12 +49,12 @@ EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# store new root password
|
# store new root password
|
||||||
echo "$mysql_password" | sudo tee /etc/yunohost/mysql
|
echo "$mysql_password" | tee /etc/yunohost/mysql
|
||||||
sudo chmod 400 /etc/yunohost/mysql
|
chmod 400 /etc/yunohost/mysql
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
[[ -z "$regen_conf_files" ]] \
|
||||||
|| sudo service mysql restart
|
|| service mysql restart
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -15,7 +15,7 @@ do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
[[ -z "$regen_conf_files" ]] \
|
||||||
|| sudo service avahi-daemon restart
|
|| service avahi-daemon restart
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -14,7 +14,7 @@ do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
[[ -z "$regen_conf_files" ]] \
|
||||||
|| sudo service glances restart
|
|| service glances restart
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -26,7 +26,7 @@ do_pre_regen() {
|
||||||
ynh_validate_ip4 "$ipv4" || ipv4='127.0.0.1'
|
ynh_validate_ip4 "$ipv4" || ipv4='127.0.0.1'
|
||||||
ipv6=$(curl -s -6 https://ip6.yunohost.org 2>/dev/null || true)
|
ipv6=$(curl -s -6 https://ip6.yunohost.org 2>/dev/null || true)
|
||||||
ynh_validate_ip6 "$ipv6" || ipv6=''
|
ynh_validate_ip6 "$ipv6" || ipv6=''
|
||||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet)
|
domain_list=$(yunohost domain list --output-as plain --quiet)
|
||||||
|
|
||||||
# add domain conf files
|
# add domain conf files
|
||||||
for domain in $domain_list; do
|
for domain in $domain_list; do
|
||||||
|
@ -50,8 +50,23 @@ do_pre_regen() {
|
||||||
do_post_regen() {
|
do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
|
# Fuck it, those domain/search entries from dhclient are usually annoying
|
||||||
|
# lying shit from the ISP trying to MiTM
|
||||||
|
if grep -q -E "^ *(domain|search)" /run/resolvconf/resolv.conf
|
||||||
|
then
|
||||||
|
if grep -q -E "^ *(domain|search)" /run/resolvconf/interface/*.dhclient 2>/dev/null
|
||||||
|
then
|
||||||
|
sed -E "s/^(domain|search)/#\1/g" -i /run/resolvconf/interface/*.dhclient
|
||||||
|
fi
|
||||||
|
|
||||||
|
grep -q '^supersede domain-name "";' /etc/dhcp/dhclient.conf 2>/dev/null || echo 'supersede domain-name "";' >> /etc/dhcp/dhclient.conf
|
||||||
|
grep -q '^supersede domain-search "";' /etc/dhcp/dhclient.conf 2>/dev/null || echo 'supersede domain-search "";' >> /etc/dhcp/dhclient.conf
|
||||||
|
grep -q '^supersede name "";' /etc/dhcp/dhclient.conf 2>/dev/null || echo 'supersede name "";' >> /etc/dhcp/dhclient.conf
|
||||||
|
systemctl restart resolvconf
|
||||||
|
fi
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
[[ -z "$regen_conf_files" ]] \
|
||||||
|| sudo service dnsmasq restart
|
|| service dnsmasq restart
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -14,7 +14,7 @@ do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
[[ -z "$regen_conf_files" ]] \
|
||||||
|| sudo service unscd restart
|
|| service unscd restart
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
|
@ -20,7 +20,7 @@ do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
[[ -z "$regen_conf_files" ]] \
|
||||||
|| sudo service fail2ban restart
|
|| service fail2ban restart
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE=${2:-0}
|
FORCE=${2:-0}
|
||||||
|
|
78
data/hooks/diagnosis/00-basesystem.py
Normal file
78
data/hooks/diagnosis/00-basesystem.py
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from moulinette.utils.process import check_output
|
||||||
|
from moulinette.utils.filesystem import read_file
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from yunohost.utils.packages import ynh_packages_version
|
||||||
|
|
||||||
|
|
||||||
|
class BaseSystemDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 600
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
# Detect virt technology (if not bare metal) and arch
|
||||||
|
# Gotta have this "|| true" because it systemd-detect-virt return 'none'
|
||||||
|
# with an error code on bare metal ~.~
|
||||||
|
virt = check_output("systemd-detect-virt || true", shell=True).strip()
|
||||||
|
if virt.lower() == "none":
|
||||||
|
virt = "bare-metal"
|
||||||
|
|
||||||
|
# Detect arch
|
||||||
|
arch = check_output("dpkg --print-architecture").strip()
|
||||||
|
hardware = dict(meta={"test": "hardware"},
|
||||||
|
status="INFO",
|
||||||
|
data={"virt": virt, "arch": arch},
|
||||||
|
summary="diagnosis_basesystem_hardware")
|
||||||
|
|
||||||
|
# Also possibly the board name
|
||||||
|
if os.path.exists("/proc/device-tree/model"):
|
||||||
|
model = read_file('/proc/device-tree/model').strip()
|
||||||
|
hardware["data"]["model"] = model
|
||||||
|
hardware["details"] = ["diagnosis_basesystem_hardware_board"]
|
||||||
|
|
||||||
|
yield hardware
|
||||||
|
|
||||||
|
# Kernel version
|
||||||
|
kernel_version = read_file('/proc/sys/kernel/osrelease').strip()
|
||||||
|
yield dict(meta={"test": "kernel"},
|
||||||
|
data={"kernel_version": kernel_version},
|
||||||
|
status="INFO",
|
||||||
|
summary="diagnosis_basesystem_kernel")
|
||||||
|
|
||||||
|
# Debian release
|
||||||
|
debian_version = read_file("/etc/debian_version").strip()
|
||||||
|
yield dict(meta={"test": "host"},
|
||||||
|
data={"debian_version": debian_version},
|
||||||
|
status="INFO",
|
||||||
|
summary="diagnosis_basesystem_host")
|
||||||
|
|
||||||
|
# Yunohost packages versions
|
||||||
|
# We check if versions are consistent (e.g. all 3.6 and not 3 packages with 3.6 and the other with 3.5)
|
||||||
|
# This is a classical issue for upgrades that failed in the middle
|
||||||
|
# (or people upgrading half of the package because they did 'apt upgrade' instead of 'dist-upgrade')
|
||||||
|
# Here, ynh_core_version is for example "3.5.4.12", so [:3] is "3.5" and we check it's the same for all packages
|
||||||
|
ynh_packages = ynh_packages_version()
|
||||||
|
ynh_core_version = ynh_packages["yunohost"]["version"]
|
||||||
|
consistent_versions = all(infos["version"][:3] == ynh_core_version[:3] for infos in ynh_packages.values())
|
||||||
|
ynh_version_details = [("diagnosis_basesystem_ynh_single_version",
|
||||||
|
{"package":package,
|
||||||
|
"version": infos["version"],
|
||||||
|
"repo": infos["repo"]}
|
||||||
|
)
|
||||||
|
for package, infos in ynh_packages.items()]
|
||||||
|
|
||||||
|
yield dict(meta={"test": "ynh_versions"},
|
||||||
|
data={"main_version": ynh_core_version, "repo": ynh_packages["yunohost"]["repo"]},
|
||||||
|
status="INFO" if consistent_versions else "ERROR",
|
||||||
|
summary="diagnosis_basesystem_ynh_main_version" if consistent_versions else "diagnosis_basesystem_ynh_inconsistent_versions",
|
||||||
|
details=ynh_version_details)
|
||||||
|
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return BaseSystemDiagnoser(args, env, loggers).diagnose()
|
159
data/hooks/diagnosis/10-ip.py
Normal file
159
data/hooks/diagnosis/10-ip.py
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
|
||||||
|
from moulinette.utils.network import download_text
|
||||||
|
from moulinette.utils.process import check_output
|
||||||
|
from moulinette.utils.filesystem import read_file
|
||||||
|
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from yunohost.utils.network import get_network_interfaces
|
||||||
|
|
||||||
|
class IPDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 600
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
# ############################################################ #
|
||||||
|
# PING : Check that we can ping outside at least in ipv4 or v6 #
|
||||||
|
# ############################################################ #
|
||||||
|
|
||||||
|
can_ping_ipv4 = self.can_ping_outside(4)
|
||||||
|
can_ping_ipv6 = self.can_ping_outside(6)
|
||||||
|
|
||||||
|
if not can_ping_ipv4 and not can_ping_ipv6:
|
||||||
|
yield dict(meta={"test": "ping"},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_ip_not_connected_at_all")
|
||||||
|
# Not much else we can do if there's no internet at all
|
||||||
|
return
|
||||||
|
|
||||||
|
# ###################################################### #
|
||||||
|
# DNS RESOLUTION : Check that we can resolve domain name #
|
||||||
|
# (later needed to talk to ip. and ip6.yunohost.org) #
|
||||||
|
# ###################################################### #
|
||||||
|
|
||||||
|
can_resolve_dns = self.can_resolve_dns()
|
||||||
|
|
||||||
|
# In every case, we can check that resolvconf seems to be okay
|
||||||
|
# (symlink managed by resolvconf service + pointing to dnsmasq)
|
||||||
|
good_resolvconf = self.good_resolvconf()
|
||||||
|
|
||||||
|
# If we can't resolve domain names at all, that's a pretty big issue ...
|
||||||
|
# If it turns out that at the same time, resolvconf is bad, that's probably
|
||||||
|
# the cause of this, so we use a different message in that case
|
||||||
|
if not can_resolve_dns:
|
||||||
|
yield dict(meta={"test": "dnsresolv"},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_ip_broken_dnsresolution" if good_resolvconf else "diagnosis_ip_broken_resolvconf")
|
||||||
|
return
|
||||||
|
# Otherwise, if the resolv conf is bad but we were able to resolve domain name,
|
||||||
|
# still warn that we're using a weird resolv conf ...
|
||||||
|
elif not good_resolvconf:
|
||||||
|
yield dict(meta={"test": "dnsresolv"},
|
||||||
|
status="WARNING",
|
||||||
|
summary="diagnosis_ip_weird_resolvconf",
|
||||||
|
details=["diagnosis_ip_weird_resolvconf_details"])
|
||||||
|
else:
|
||||||
|
yield dict(meta={"test": "dnsresolv"},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_ip_dnsresolution_working")
|
||||||
|
|
||||||
|
# ##################################################### #
|
||||||
|
# IP DIAGNOSIS : Check that we're actually able to talk #
|
||||||
|
# to a web server to fetch current IPv4 and v6 #
|
||||||
|
# ##################################################### #
|
||||||
|
|
||||||
|
ipv4 = self.get_public_ip(4) if can_ping_ipv4 else None
|
||||||
|
ipv6 = self.get_public_ip(6) if can_ping_ipv6 else None
|
||||||
|
|
||||||
|
network_interfaces = get_network_interfaces()
|
||||||
|
def get_local_ip(version):
|
||||||
|
local_ip = {iface:addr[version].split("/")[0]
|
||||||
|
for iface, addr in network_interfaces.items() if version in addr}
|
||||||
|
if not local_ip:
|
||||||
|
return None
|
||||||
|
elif len(local_ip):
|
||||||
|
return next(iter(local_ip.values()))
|
||||||
|
else:
|
||||||
|
return local_ip
|
||||||
|
|
||||||
|
yield dict(meta={"test": "ipv4"},
|
||||||
|
data={"global": ipv4, "local": get_local_ip("ipv4")},
|
||||||
|
status="SUCCESS" if ipv4 else "ERROR",
|
||||||
|
summary="diagnosis_ip_connected_ipv4" if ipv4 else "diagnosis_ip_no_ipv4",
|
||||||
|
details=["diagnosis_ip_global", "diagnosis_ip_local"] if ipv4 else None)
|
||||||
|
|
||||||
|
yield dict(meta={"test": "ipv6"},
|
||||||
|
data={"global": ipv6, "local": get_local_ip("ipv6")},
|
||||||
|
status="SUCCESS" if ipv6 else "WARNING",
|
||||||
|
summary="diagnosis_ip_connected_ipv6" if ipv6 else "diagnosis_ip_no_ipv6",
|
||||||
|
details=["diagnosis_ip_global", "diagnosis_ip_local"] if ipv6 else None)
|
||||||
|
|
||||||
|
# TODO / FIXME : add some attempt to detect ISP (using whois ?) ?
|
||||||
|
|
||||||
|
def can_ping_outside(self, protocol=4):
|
||||||
|
|
||||||
|
assert protocol in [4, 6], "Invalid protocol version, it should be either 4 or 6 and was '%s'" % repr(protocol)
|
||||||
|
|
||||||
|
# We can know that ipv6 is not available directly if this file does not exists
|
||||||
|
if protocol == 6 and not os.path.exists("/proc/net/if_inet6"):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# If we are indeed connected in ipv4 or ipv6, we should find a default route
|
||||||
|
routes = check_output("ip -%s route" % protocol).split("\n")
|
||||||
|
if not any(r.startswith("default") for r in routes):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# We use the resolver file as a list of well-known, trustable (ie not google ;)) IPs that we can ping
|
||||||
|
resolver_file = "/usr/share/yunohost/templates/dnsmasq/plain/resolv.dnsmasq.conf"
|
||||||
|
resolvers = [r.split(" ")[1] for r in read_file(resolver_file).split("\n") if r.startswith("nameserver")]
|
||||||
|
|
||||||
|
if protocol == 4:
|
||||||
|
resolvers = [r for r in resolvers if ":" not in r]
|
||||||
|
if protocol == 6:
|
||||||
|
resolvers = [r for r in resolvers if ":" in r]
|
||||||
|
|
||||||
|
assert resolvers != [], "Uhoh, need at least one IPv%s DNS resolver in %s ..." % (protocol, resolver_file)
|
||||||
|
|
||||||
|
# So let's try to ping the first 4~5 resolvers (shuffled)
|
||||||
|
# If we succesfully ping any of them, we conclude that we are indeed connected
|
||||||
|
def ping(protocol, target):
|
||||||
|
return os.system("ping%s -c1 -W 3 %s >/dev/null 2>/dev/null" % ("" if protocol == 4 else "6", target)) == 0
|
||||||
|
|
||||||
|
random.shuffle(resolvers)
|
||||||
|
return any(ping(protocol, resolver) for resolver in resolvers[:5])
|
||||||
|
|
||||||
|
def can_resolve_dns(self):
|
||||||
|
return os.system("dig +short ip.yunohost.org >/dev/null 2>/dev/null") == 0
|
||||||
|
|
||||||
|
def good_resolvconf(self):
|
||||||
|
content = read_file("/etc/resolv.conf").strip().split("\n")
|
||||||
|
# Ignore comments and empty lines
|
||||||
|
content = [l.strip() for l in content if l.strip() and not l.strip().startswith("#") and not l.strip().startswith("search")]
|
||||||
|
# We should only find a "nameserver 127.0.0.1"
|
||||||
|
return len(content) == 1 and content[0].split() == ["nameserver", "127.0.0.1"]
|
||||||
|
|
||||||
|
def get_public_ip(self, protocol=4):
|
||||||
|
|
||||||
|
# FIXME - TODO : here we assume that DNS resolution for ip.yunohost.org is working
|
||||||
|
# but if we want to be able to diagnose DNS resolution issues independently from
|
||||||
|
# internet connectivity, we gotta rely on fixed IPs first....
|
||||||
|
|
||||||
|
assert protocol in [4, 6], "Invalid protocol version, it should be either 4 or 6 and was '%s'" % repr(protocol)
|
||||||
|
|
||||||
|
url = 'https://ip%s.yunohost.org' % ('6' if protocol == 6 else '')
|
||||||
|
|
||||||
|
try:
|
||||||
|
return download_text(url, timeout=30).strip()
|
||||||
|
except Exception as e:
|
||||||
|
self.logger_debug("Could not get public IPv%s : %s" % (str(protocol), str(e)))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return IPDiagnoser(args, env, loggers).diagnose()
|
141
data/hooks/diagnosis/12-dnsrecords.py
Normal file
141
data/hooks/diagnosis/12-dnsrecords.py
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from moulinette.utils.filesystem import read_file
|
||||||
|
|
||||||
|
from yunohost.utils.network import dig
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from yunohost.domain import domain_list, _build_dns_conf, _get_maindomain
|
||||||
|
|
||||||
|
|
||||||
|
class DNSRecordsDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 600
|
||||||
|
dependencies = ["ip"]
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
resolvers = read_file("/etc/resolv.dnsmasq.conf").split("\n")
|
||||||
|
ipv4_resolvers = [r.split(" ")[1] for r in resolvers if r.startswith("nameserver") and ":" not in r]
|
||||||
|
# FIXME some day ... handle ipv4-only and ipv6-only servers. For now we assume we have at least ipv4
|
||||||
|
assert ipv4_resolvers != [], "Uhoh, need at least one IPv4 DNS resolver ..."
|
||||||
|
|
||||||
|
self.resolver = ipv4_resolvers[0]
|
||||||
|
main_domain = _get_maindomain()
|
||||||
|
|
||||||
|
all_domains = domain_list()["domains"]
|
||||||
|
for domain in all_domains:
|
||||||
|
self.logger_debug("Diagnosing DNS conf for %s" % domain)
|
||||||
|
is_subdomain = domain.split(".",1)[1] in all_domains
|
||||||
|
for report in self.check_domain(domain, domain == main_domain, is_subdomain=is_subdomain):
|
||||||
|
yield report
|
||||||
|
|
||||||
|
# FIXME : somewhere, should implement a check for reverse DNS ...
|
||||||
|
|
||||||
|
# FIXME / TODO : somewhere, could also implement a check for domain expiring soon
|
||||||
|
|
||||||
|
def check_domain(self, domain, is_main_domain, is_subdomain):
|
||||||
|
|
||||||
|
expected_configuration = _build_dns_conf(domain, include_empty_AAAA_if_no_ipv6=True)
|
||||||
|
|
||||||
|
categories = ["basic", "mail", "xmpp", "extra"]
|
||||||
|
# For subdomains, we only diagnosis A and AAAA records
|
||||||
|
if is_subdomain:
|
||||||
|
categories = ["basic"]
|
||||||
|
|
||||||
|
for category in categories:
|
||||||
|
|
||||||
|
records = expected_configuration[category]
|
||||||
|
discrepancies = []
|
||||||
|
results = {}
|
||||||
|
|
||||||
|
for r in records:
|
||||||
|
id_ = r["type"] + ":" + r["name"]
|
||||||
|
r["current"] = self.get_current_record(domain, r["name"], r["type"])
|
||||||
|
if r["value"] == "@":
|
||||||
|
r["value"] = domain + "."
|
||||||
|
|
||||||
|
if self.current_record_match_expected(r):
|
||||||
|
results[id_] = "OK"
|
||||||
|
else:
|
||||||
|
if r["current"] is None:
|
||||||
|
results[id_] = "MISSING"
|
||||||
|
discrepancies.append(("diagnosis_dns_missing_record", r))
|
||||||
|
else:
|
||||||
|
results[id_] = "WRONG"
|
||||||
|
discrepancies.append(("diagnosis_dns_discrepancy", r))
|
||||||
|
|
||||||
|
|
||||||
|
def its_important():
|
||||||
|
# Every mail DNS records are important for main domain
|
||||||
|
# For other domain, we only report it as a warning for now...
|
||||||
|
if is_main_domain and category == "mail":
|
||||||
|
return True
|
||||||
|
elif category == "basic":
|
||||||
|
# A bad or missing A record is critical ...
|
||||||
|
# And so is a wrong AAAA record
|
||||||
|
# (However, a missing AAAA record is acceptable)
|
||||||
|
if results["A:@"] != "OK" or results["AAAA:@"] == "WRONG":
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
if discrepancies:
|
||||||
|
status = "ERROR" if its_important() else "WARNING"
|
||||||
|
summary = "diagnosis_dns_bad_conf"
|
||||||
|
else:
|
||||||
|
status = "SUCCESS"
|
||||||
|
summary = "diagnosis_dns_good_conf"
|
||||||
|
|
||||||
|
output = dict(meta={"domain": domain, "category": category},
|
||||||
|
data=results,
|
||||||
|
status=status,
|
||||||
|
summary=summary)
|
||||||
|
|
||||||
|
if discrepancies:
|
||||||
|
output["details"] = ["diagnosis_dns_point_to_doc"] + discrepancies
|
||||||
|
|
||||||
|
yield output
|
||||||
|
|
||||||
|
def get_current_record(self, domain, name, type_):
|
||||||
|
|
||||||
|
query = "%s.%s" % (name, domain) if name != "@" else domain
|
||||||
|
success, answers = dig(query, type_, resolvers="force_external")
|
||||||
|
|
||||||
|
if success != "ok":
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return answers[0] if len(answers) == 1 else answers
|
||||||
|
|
||||||
|
def current_record_match_expected(self, r):
|
||||||
|
if r["value"] is not None and r["current"] is None:
|
||||||
|
return False
|
||||||
|
if r["value"] is None and r["current"] is not None:
|
||||||
|
return False
|
||||||
|
elif isinstance(r["current"], list):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if r["type"] == "TXT":
|
||||||
|
# Split expected/current
|
||||||
|
# from "v=DKIM1; k=rsa; p=hugekey;"
|
||||||
|
# to a set like {'v=DKIM1', 'k=rsa', 'p=...'}
|
||||||
|
expected = set(r["value"].strip(';" ').replace(";", " ").split())
|
||||||
|
current = set(r["current"].strip(';" ').replace(";", " ").split())
|
||||||
|
|
||||||
|
# For SPF, ignore parts starting by ip4: or ip6:
|
||||||
|
if r["name"] == "@":
|
||||||
|
current = {part for part in current if not part.startswith("ip4:") and not part.startswith("ip6:")}
|
||||||
|
return expected == current
|
||||||
|
elif r["type"] == "MX":
|
||||||
|
# For MX, we want to ignore the priority
|
||||||
|
expected = r["value"].split()[-1]
|
||||||
|
current = r["current"].split()[-1]
|
||||||
|
return expected == current
|
||||||
|
else:
|
||||||
|
return r["current"] == r["value"]
|
||||||
|
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return DNSRecordsDiagnoser(args, env, loggers).diagnose()
|
116
data/hooks/diagnosis/14-ports.py
Normal file
116
data/hooks/diagnosis/14-ports.py
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from yunohost.utils.error import YunohostError
|
||||||
|
from yunohost.service import _get_services
|
||||||
|
|
||||||
|
class PortsDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 600
|
||||||
|
dependencies = ["ip"]
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
# TODO: report a warning if port 53 or 5353 is exposed to the outside world...
|
||||||
|
|
||||||
|
# This dict is something like :
|
||||||
|
# { 80: "nginx",
|
||||||
|
# 25: "postfix",
|
||||||
|
# 443: "nginx"
|
||||||
|
# ... }
|
||||||
|
ports = {}
|
||||||
|
services = _get_services()
|
||||||
|
for service, infos in services.items():
|
||||||
|
for port in infos.get("needs_exposed_ports", []):
|
||||||
|
ports[port] = service
|
||||||
|
|
||||||
|
ipversions = []
|
||||||
|
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
|
||||||
|
if ipv4.get("status") == "SUCCESS":
|
||||||
|
ipversions.append(4)
|
||||||
|
|
||||||
|
# To be discussed: we could also make this check dependent on the
|
||||||
|
# existence of an AAAA record...
|
||||||
|
ipv6 = Diagnoser.get_cached_report("ip", item={"test": "ipv6"}) or {}
|
||||||
|
if ipv6.get("status") == "SUCCESS":
|
||||||
|
ipversions.append(6)
|
||||||
|
|
||||||
|
# Fetch test result for each relevant IP version
|
||||||
|
results = {}
|
||||||
|
for ipversion in ipversions:
|
||||||
|
try:
|
||||||
|
r = Diagnoser.remote_diagnosis('check-ports',
|
||||||
|
data={'ports': ports.keys()},
|
||||||
|
ipversion=ipversion)
|
||||||
|
results[ipversion] = r["ports"]
|
||||||
|
except Exception as e:
|
||||||
|
yield dict(meta={"reason": "remote_diagnosis_failed", "ipversion": ipversion},
|
||||||
|
data={"error": str(e)},
|
||||||
|
status="WARNING",
|
||||||
|
summary="diagnosis_ports_could_not_diagnose",
|
||||||
|
details=["diagnosis_ports_could_not_diagnose_details"])
|
||||||
|
continue
|
||||||
|
|
||||||
|
ipversions = results.keys()
|
||||||
|
if not ipversions:
|
||||||
|
return
|
||||||
|
|
||||||
|
for port, service in sorted(ports.items()):
|
||||||
|
port = str(port)
|
||||||
|
category = services[service].get("category", "[?]")
|
||||||
|
|
||||||
|
# If both IPv4 and IPv6 (if applicable) are good
|
||||||
|
if all(results[ipversion].get(port) is True for ipversion in ipversions):
|
||||||
|
yield dict(meta={"port": port},
|
||||||
|
data={"service": service, "category": category},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_ports_ok",
|
||||||
|
details=["diagnosis_ports_needed_by"])
|
||||||
|
# If both IPv4 and IPv6 (if applicable) are failed
|
||||||
|
elif all(results[ipversion].get(port) is not True for ipversion in ipversions):
|
||||||
|
yield dict(meta={"port": port},
|
||||||
|
data={"service": service, "category": category},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_ports_unreachable",
|
||||||
|
details=["diagnosis_ports_needed_by", "diagnosis_ports_forwarding_tip"])
|
||||||
|
# If only IPv4 is failed or only IPv6 is failed (if applicable)
|
||||||
|
else:
|
||||||
|
passed, failed = (4, 6) if results[4].get(port) is True else (6, 4)
|
||||||
|
|
||||||
|
# Failing in ipv4 is critical.
|
||||||
|
# If we failed in IPv6 but there's in fact no AAAA record
|
||||||
|
# It's an acceptable situation and we shall not report an
|
||||||
|
# error
|
||||||
|
# If any AAAA record is set, IPv6 is important...
|
||||||
|
def ipv6_is_important():
|
||||||
|
dnsrecords = Diagnoser.get_cached_report("dnsrecords") or {}
|
||||||
|
return any(record["data"]["AAAA:@"] in ["OK", "WRONG"] for record in dnsrecords.get("items", []))
|
||||||
|
|
||||||
|
if failed == 4 or ipv6_is_important():
|
||||||
|
yield dict(meta={"port": port},
|
||||||
|
data={"service": service, "category": category, "passed": passed, "failed": failed},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_ports_partially_unreachable",
|
||||||
|
details=["diagnosis_ports_needed_by", "diagnosis_ports_forwarding_tip"])
|
||||||
|
# So otherwise we report a success
|
||||||
|
# And in addition we report an info about the failure in IPv6
|
||||||
|
# *with a different meta* (important to avoid conflicts when
|
||||||
|
# fetching the other info...)
|
||||||
|
else:
|
||||||
|
yield dict(meta={"port": port},
|
||||||
|
data={"service": service, "category": category},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_ports_ok",
|
||||||
|
details=["diagnosis_ports_needed_by"])
|
||||||
|
yield dict(meta={"test": "ipv6", "port": port},
|
||||||
|
data={"service": service, "category": category, "passed": passed, "failed": failed},
|
||||||
|
status="INFO",
|
||||||
|
summary="diagnosis_ports_partially_unreachable",
|
||||||
|
details=["diagnosis_ports_needed_by", "diagnosis_ports_forwarding_tip"])
|
||||||
|
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return PortsDiagnoser(args, env, loggers).diagnose()
|
166
data/hooks/diagnosis/21-web.py
Normal file
166
data/hooks/diagnosis/21-web.py
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from moulinette.utils.filesystem import read_file
|
||||||
|
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from yunohost.domain import domain_list
|
||||||
|
from yunohost.utils.error import YunohostError
|
||||||
|
|
||||||
|
DIAGNOSIS_SERVER = "diagnosis.yunohost.org"
|
||||||
|
|
||||||
|
|
||||||
|
class WebDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 600
|
||||||
|
dependencies = ["ip"]
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
all_domains = domain_list()["domains"]
|
||||||
|
domains_to_check = []
|
||||||
|
for domain in all_domains:
|
||||||
|
|
||||||
|
# If the diagnosis location ain't defined, can't do diagnosis,
|
||||||
|
# probably because nginx conf manually modified...
|
||||||
|
nginx_conf = "/etc/nginx/conf.d/%s.conf" % domain
|
||||||
|
if ".well-known/ynh-diagnosis/" not in read_file(nginx_conf):
|
||||||
|
yield dict(meta={"domain": domain},
|
||||||
|
status="WARNING",
|
||||||
|
summary="diagnosis_http_nginx_conf_not_up_to_date",
|
||||||
|
details=["diagnosis_http_nginx_conf_not_up_to_date_details"])
|
||||||
|
else:
|
||||||
|
domains_to_check.append(domain)
|
||||||
|
|
||||||
|
self.nonce = ''.join(random.choice("0123456789abcedf") for i in range(16))
|
||||||
|
os.system("rm -rf /tmp/.well-known/ynh-diagnosis/")
|
||||||
|
os.system("mkdir -p /tmp/.well-known/ynh-diagnosis/")
|
||||||
|
os.system("touch /tmp/.well-known/ynh-diagnosis/%s" % self.nonce)
|
||||||
|
|
||||||
|
if not domains_to_check:
|
||||||
|
return
|
||||||
|
|
||||||
|
# To perform hairpinning test, we gotta make sure that port forwarding
|
||||||
|
# is working and therefore we'll do it only if at least one ipv4 domain
|
||||||
|
# works.
|
||||||
|
self.do_hairpinning_test = False
|
||||||
|
|
||||||
|
ipversions = []
|
||||||
|
ipv4 = Diagnoser.get_cached_report("ip", item={"test": "ipv4"}) or {}
|
||||||
|
if ipv4.get("status") == "SUCCESS":
|
||||||
|
ipversions.append(4)
|
||||||
|
|
||||||
|
# To be discussed: we could also make this check dependent on the
|
||||||
|
# existence of an AAAA record...
|
||||||
|
ipv6 = Diagnoser.get_cached_report("ip", item={"test": "ipv6"}) or {}
|
||||||
|
if ipv6.get("status") == "SUCCESS":
|
||||||
|
ipversions.append(6)
|
||||||
|
|
||||||
|
for item in self.test_http(domains_to_check, ipversions):
|
||||||
|
yield item
|
||||||
|
|
||||||
|
# If at least one domain is correctly exposed to the outside,
|
||||||
|
# attempt to diagnose hairpinning situations. On network with
|
||||||
|
# hairpinning issues, the server may be correctly exposed on the
|
||||||
|
# outside, but from the outside, it will be as if the port forwarding
|
||||||
|
# was not configured... Hence, calling for example
|
||||||
|
# "curl --head the.global.ip" will simply timeout...
|
||||||
|
if self.do_hairpinning_test:
|
||||||
|
global_ipv4 = ipv4.get("data", {}).get("global", None)
|
||||||
|
if global_ipv4:
|
||||||
|
try:
|
||||||
|
requests.head("http://" + global_ipv4, timeout=5)
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
yield dict(meta={"test": "hairpinning"},
|
||||||
|
status="WARNING",
|
||||||
|
summary="diagnosis_http_hairpinning_issue",
|
||||||
|
details=["diagnosis_http_hairpinning_issue_details"])
|
||||||
|
except:
|
||||||
|
# Well I dunno what to do if that's another exception
|
||||||
|
# type... That'll most probably *not* be an hairpinning
|
||||||
|
# issue but something else super weird ...
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_http(self, domains, ipversions):
|
||||||
|
|
||||||
|
results = {}
|
||||||
|
for ipversion in ipversions:
|
||||||
|
try:
|
||||||
|
r = Diagnoser.remote_diagnosis('check-http',
|
||||||
|
data={'domains': domains,
|
||||||
|
"nonce": self.nonce},
|
||||||
|
ipversion=ipversion)
|
||||||
|
results[ipversion] = r["http"]
|
||||||
|
except Exception as e:
|
||||||
|
yield dict(meta={"reason": "remote_diagnosis_failed", "ipversion": ipversion},
|
||||||
|
data={"error": str(e)},
|
||||||
|
status="WARNING",
|
||||||
|
summary="diagnosis_http_could_not_diagnose",
|
||||||
|
details=["diagnosis_http_could_not_diagnose_details"])
|
||||||
|
continue
|
||||||
|
|
||||||
|
ipversions = results.keys()
|
||||||
|
if not ipversions:
|
||||||
|
return
|
||||||
|
|
||||||
|
for domain in domains:
|
||||||
|
|
||||||
|
# If both IPv4 and IPv6 (if applicable) are good
|
||||||
|
if all(results[ipversion][domain]["status"] == "ok" for ipversion in ipversions):
|
||||||
|
if 4 in ipversions:
|
||||||
|
self.do_hairpinning_test = True
|
||||||
|
yield dict(meta={"domain": domain},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_http_ok")
|
||||||
|
# If both IPv4 and IPv6 (if applicable) are failed
|
||||||
|
elif all(results[ipversion][domain]["status"] != "ok" for ipversion in ipversions):
|
||||||
|
detail = results[4 if 4 in ipversions else 6][domain]["status"]
|
||||||
|
yield dict(meta={"domain": domain},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_http_unreachable",
|
||||||
|
details=[detail.replace("error_http_check", "diagnosis_http")])
|
||||||
|
# If only IPv4 is failed or only IPv6 is failed (if applicable)
|
||||||
|
else:
|
||||||
|
passed, failed = (4, 6) if results[4][domain]["status"] == "ok" else (6, 4)
|
||||||
|
detail = results[failed][domain]["status"]
|
||||||
|
|
||||||
|
# Failing in ipv4 is critical.
|
||||||
|
# If we failed in IPv6 but there's in fact no AAAA record
|
||||||
|
# It's an acceptable situation and we shall not report an
|
||||||
|
# error
|
||||||
|
def ipv6_is_important_for_this_domain():
|
||||||
|
dnsrecords = Diagnoser.get_cached_report("dnsrecords", item={"domain": domain, "category": "basic"}) or {}
|
||||||
|
AAAA_status = dnsrecords.get("data", {}).get("AAAA:@")
|
||||||
|
|
||||||
|
return AAAA_status in ["OK", "WRONG"]
|
||||||
|
|
||||||
|
if failed == 4 or ipv6_is_important_for_this_domain():
|
||||||
|
yield dict(meta={"domain": domain},
|
||||||
|
data={"passed": passed, "failed": failed},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_http_partially_unreachable",
|
||||||
|
details=[detail.replace("error_http_check", "diagnosis_http")])
|
||||||
|
# So otherwise we report a success (note that this info is
|
||||||
|
# later used to know that ACME challenge is doable)
|
||||||
|
#
|
||||||
|
# And in addition we report an info about the failure in IPv6
|
||||||
|
# *with a different meta* (important to avoid conflicts when
|
||||||
|
# fetching the other info...)
|
||||||
|
else:
|
||||||
|
self.do_hairpinning_test = True
|
||||||
|
yield dict(meta={"domain": domain},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_http_ok")
|
||||||
|
yield dict(meta={"test": "ipv6", "domain": domain},
|
||||||
|
data={"passed": passed, "failed": failed},
|
||||||
|
status="INFO",
|
||||||
|
summary="diagnosis_http_partially_unreachable",
|
||||||
|
details=[detail.replace("error_http_check", "diagnosis_http")])
|
||||||
|
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return WebDiagnoser(args, env, loggers).diagnose()
|
238
data/hooks/diagnosis/24-mail.py
Normal file
238
data/hooks/diagnosis/24-mail.py
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import dns.resolver
|
||||||
|
import socket
|
||||||
|
import re
|
||||||
|
|
||||||
|
from subprocess import CalledProcessError
|
||||||
|
|
||||||
|
from moulinette.utils.process import check_output
|
||||||
|
from moulinette.utils.filesystem import read_yaml
|
||||||
|
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from yunohost.domain import _get_maindomain, domain_list
|
||||||
|
from yunohost.settings import settings_get
|
||||||
|
from yunohost.utils.network import dig
|
||||||
|
|
||||||
|
DEFAULT_DNS_BLACKLIST = "/usr/share/yunohost/other/dnsbl_list.yml"
|
||||||
|
|
||||||
|
|
||||||
|
class MailDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 600
|
||||||
|
dependencies = ["ip"]
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
self.ehlo_domain = _get_maindomain()
|
||||||
|
self.mail_domains = domain_list()["domains"]
|
||||||
|
self.ipversions, self.ips = self.get_ips_checked()
|
||||||
|
|
||||||
|
# TODO Is a A/AAAA and MX Record ?
|
||||||
|
# TODO Are outgoing public IPs authorized to send mail by SPF ?
|
||||||
|
# TODO Validate DKIM and dmarc ?
|
||||||
|
# TODO check that the recent mail logs are not filled with thousand of email sending (unusual number of mail sent)
|
||||||
|
# TODO check for unusual failed sending attempt being refused in the logs ?
|
||||||
|
checks = ["check_outgoing_port_25", "check_ehlo", "check_fcrdns",
|
||||||
|
"check_blacklist", "check_queue"]
|
||||||
|
for check in checks:
|
||||||
|
self.logger_debug("Running " + check)
|
||||||
|
reports = list(getattr(self, check)())
|
||||||
|
for report in reports:
|
||||||
|
yield report
|
||||||
|
if not reports:
|
||||||
|
name = check[6:]
|
||||||
|
yield dict(meta={"test": "mail_" + name},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_mail_" + name + "_ok")
|
||||||
|
|
||||||
|
|
||||||
|
def check_outgoing_port_25(self):
|
||||||
|
"""
|
||||||
|
Check outgoing port 25 is open and not blocked by router
|
||||||
|
This check is ran on IPs we could used to send mail.
|
||||||
|
"""
|
||||||
|
|
||||||
|
for ipversion in self.ipversions:
|
||||||
|
cmd = '/bin/nc -{ipversion} -z -w2 yunohost.org 25'.format(ipversion=ipversion)
|
||||||
|
if os.system(cmd) != 0:
|
||||||
|
yield dict(meta={"test": "outgoing_port_25", "ipversion": ipversion},
|
||||||
|
data={},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_mail_outgoing_port_25_blocked",
|
||||||
|
details=["diagnosis_mail_outgoing_port_25_blocked_details",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked_relay_vpn"])
|
||||||
|
|
||||||
|
|
||||||
|
def check_ehlo(self):
|
||||||
|
"""
|
||||||
|
Check the server is reachable from outside and it's the good one
|
||||||
|
This check is ran on IPs we could used to send mail.
|
||||||
|
"""
|
||||||
|
|
||||||
|
for ipversion in self.ipversions:
|
||||||
|
try:
|
||||||
|
r = Diagnoser.remote_diagnosis('check-smtp',
|
||||||
|
data={},
|
||||||
|
ipversion=ipversion)
|
||||||
|
except Exception as e:
|
||||||
|
yield dict(meta={"test": "mail_ehlo", "reason": "remote_server_failed",
|
||||||
|
"ipversion": ipversion},
|
||||||
|
data={"error": str(e)},
|
||||||
|
status="WARNING",
|
||||||
|
summary="diagnosis_mail_ehlo_could_not_diagnose",
|
||||||
|
details=["diagnosis_mail_ehlo_could_not_diagnose_details"])
|
||||||
|
continue
|
||||||
|
|
||||||
|
if r["status"] != "ok":
|
||||||
|
summary = r["status"].replace("error_smtp_", "diagnosis_mail_ehlo_")
|
||||||
|
yield dict(meta={"test": "mail_ehlo", "ipversion": ipversion},
|
||||||
|
data={},
|
||||||
|
status="ERROR",
|
||||||
|
summary=summary,
|
||||||
|
details=[summary + "_details"])
|
||||||
|
elif r["helo"] != self.ehlo_domain:
|
||||||
|
yield dict(meta={"test": "mail_ehlo", "ipversion": ipversion},
|
||||||
|
data={"wrong_ehlo": r["helo"], "right_ehlo": self.ehlo_domain},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_mail_ehlo_wrong",
|
||||||
|
details=["diagnosis_mail_ehlo_wrong_details"])
|
||||||
|
|
||||||
|
|
||||||
|
def check_fcrdns(self):
|
||||||
|
"""
|
||||||
|
Check the reverse DNS is well defined by doing a Forward-confirmed
|
||||||
|
reverse DNS check
|
||||||
|
This check is ran on IPs we could used to send mail.
|
||||||
|
"""
|
||||||
|
|
||||||
|
for ip in self.ips:
|
||||||
|
if ":" in ip:
|
||||||
|
ipversion = 6
|
||||||
|
details = ["diagnosis_mail_fcrdns_nok_details",
|
||||||
|
"diagnosis_mail_fcrdns_nok_alternatives_6"]
|
||||||
|
else:
|
||||||
|
ipversion = 4
|
||||||
|
details = ["diagnosis_mail_fcrdns_nok_details",
|
||||||
|
"diagnosis_mail_fcrdns_nok_alternatives_4"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
rdns_domain, _, _ = socket.gethostbyaddr(ip)
|
||||||
|
except socket.herror:
|
||||||
|
yield dict(meta={"test": "mail_fcrdns", "ipversion": ipversion},
|
||||||
|
data={"ip": ip, "ehlo_domain": self.ehlo_domain},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_mail_fcrdns_dns_missing",
|
||||||
|
details=details)
|
||||||
|
continue
|
||||||
|
if rdns_domain != self.ehlo_domain:
|
||||||
|
details = ["diagnosis_mail_fcrdns_different_from_ehlo_domain_details"] + details
|
||||||
|
yield dict(meta={"test": "mail_fcrdns", "ipversion": ipversion},
|
||||||
|
data={"ip": ip,
|
||||||
|
"ehlo_domain": self.ehlo_domain,
|
||||||
|
"rdns_domain": rdns_domain},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_mail_fcrdns_different_from_ehlo_domain",
|
||||||
|
details=details)
|
||||||
|
|
||||||
|
|
||||||
|
def check_blacklist(self):
|
||||||
|
"""
|
||||||
|
Check with dig onto blacklist DNS server
|
||||||
|
This check is ran on IPs and domains we could used to send mail.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dns_blacklists = read_yaml(DEFAULT_DNS_BLACKLIST)
|
||||||
|
for item in self.ips + self.mail_domains:
|
||||||
|
for blacklist in dns_blacklists:
|
||||||
|
item_type = "domain"
|
||||||
|
if ":" in item:
|
||||||
|
item_type = 'ipv6'
|
||||||
|
elif re.match(r'^\d+\.\d+\.\d+\.\d+$', item):
|
||||||
|
item_type = 'ipv4'
|
||||||
|
|
||||||
|
if not blacklist[item_type]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Build the query for DNSBL
|
||||||
|
subdomain = item
|
||||||
|
if item_type != "domain":
|
||||||
|
rev = dns.reversename.from_address(item)
|
||||||
|
subdomain = str(rev.split(3)[0])
|
||||||
|
query = subdomain + '.' + blacklist['dns_server']
|
||||||
|
|
||||||
|
# Do the DNS Query
|
||||||
|
status, _ = dig(query, 'A')
|
||||||
|
if status != 'ok':
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Try to get the reason
|
||||||
|
details = []
|
||||||
|
status, answers = dig(query, 'TXT')
|
||||||
|
reason = "-"
|
||||||
|
if status == 'ok':
|
||||||
|
reason = ', '.join(answers)
|
||||||
|
details.append("diagnosis_mail_blacklist_reason")
|
||||||
|
|
||||||
|
details.append("diagnosis_mail_blacklist_website")
|
||||||
|
|
||||||
|
yield dict(meta={"test": "mail_blacklist", "item": item,
|
||||||
|
"blacklist": blacklist["dns_server"]},
|
||||||
|
data={'blacklist_name': blacklist['name'],
|
||||||
|
'blacklist_website': blacklist['website'],
|
||||||
|
'reason': reason},
|
||||||
|
status="ERROR",
|
||||||
|
summary='diagnosis_mail_blacklist_listed_by',
|
||||||
|
details=details)
|
||||||
|
|
||||||
|
def check_queue(self):
|
||||||
|
"""
|
||||||
|
Check mail queue is not filled with hundreds of email pending
|
||||||
|
"""
|
||||||
|
|
||||||
|
command = 'postqueue -p | grep -v "Mail queue is empty" | grep -c "^[A-Z0-9]" || true'
|
||||||
|
try:
|
||||||
|
output = check_output(command).strip()
|
||||||
|
pending_emails = int(output)
|
||||||
|
except (ValueError, CalledProcessError) as e:
|
||||||
|
yield dict(meta={"test": "mail_queue"},
|
||||||
|
data={"error": str(e)},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_mail_queue_unavailable",
|
||||||
|
details="diagnosis_mail_queue_unavailable_details")
|
||||||
|
else:
|
||||||
|
if pending_emails > 100:
|
||||||
|
yield dict(meta={"test": "mail_queue"},
|
||||||
|
data={'nb_pending': pending_emails},
|
||||||
|
status="WARNING",
|
||||||
|
summary="diagnosis_mail_queue_too_big")
|
||||||
|
else:
|
||||||
|
yield dict(meta={"test": "mail_queue"},
|
||||||
|
data={'nb_pending': pending_emails},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_mail_queue_ok")
|
||||||
|
|
||||||
|
|
||||||
|
def get_ips_checked(self):
|
||||||
|
outgoing_ipversions = []
|
||||||
|
outgoing_ips = []
|
||||||
|
ipv4 = Diagnoser.get_cached_report("ip", {"test": "ipv4"}) or {}
|
||||||
|
if ipv4.get("status") == "SUCCESS":
|
||||||
|
outgoing_ipversions.append(4)
|
||||||
|
global_ipv4 = ipv4.get("data", {}).get("global", {})
|
||||||
|
if global_ipv4:
|
||||||
|
outgoing_ips.append(global_ipv4)
|
||||||
|
|
||||||
|
if settings_get("smtp.allow_ipv6"):
|
||||||
|
ipv6 = Diagnoser.get_cached_report("ip", {"test": "ipv6"}) or {}
|
||||||
|
if ipv6.get("status") == "SUCCESS":
|
||||||
|
outgoing_ipversions.append(6)
|
||||||
|
global_ipv6 = ipv6.get("data", {}).get("global", {})
|
||||||
|
if global_ipv6:
|
||||||
|
outgoing_ips.append(global_ipv6)
|
||||||
|
return (outgoing_ipversions, outgoing_ips)
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return MailDiagnoser(args, env, loggers).diagnose()
|
40
data/hooks/diagnosis/30-services.py
Normal file
40
data/hooks/diagnosis/30-services.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from yunohost.service import service_status
|
||||||
|
|
||||||
|
class ServicesDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 300
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
all_result = service_status()
|
||||||
|
|
||||||
|
for service, result in sorted(all_result.items()):
|
||||||
|
|
||||||
|
item = dict(meta={"service": service},
|
||||||
|
data={"status": result["status"], "configuration": result["configuration"]})
|
||||||
|
|
||||||
|
if result["status"] != "running":
|
||||||
|
item["status"] = "ERROR"
|
||||||
|
item["summary"] = "diagnosis_services_bad_status"
|
||||||
|
item["details"] = ["diagnosis_services_bad_status_tip"]
|
||||||
|
|
||||||
|
elif result["configuration"] == "broken":
|
||||||
|
item["status"] = "WARNING"
|
||||||
|
item["summary"] = "diagnosis_services_conf_broken"
|
||||||
|
item["details"] = result["configuration-details"]
|
||||||
|
|
||||||
|
else:
|
||||||
|
item["status"] = "SUCCESS"
|
||||||
|
item["summary"] = "diagnosis_services_running"
|
||||||
|
|
||||||
|
yield item
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return ServicesDiagnoser(args, env, loggers).diagnose()
|
121
data/hooks/diagnosis/50-systemresources.py
Normal file
121
data/hooks/diagnosis/50-systemresources.py
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import os
|
||||||
|
import psutil
|
||||||
|
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
|
||||||
|
class SystemResourcesDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 300
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
MB = 1024**2
|
||||||
|
GB = MB*1024
|
||||||
|
|
||||||
|
#
|
||||||
|
# RAM
|
||||||
|
#
|
||||||
|
|
||||||
|
ram = psutil.virtual_memory()
|
||||||
|
ram_available_percent = 100 * ram.available / ram.total
|
||||||
|
item = dict(meta={"test": "ram"},
|
||||||
|
data={"total": human_size(ram.total),
|
||||||
|
"available": human_size(ram.available),
|
||||||
|
"available_percent": round_(ram_available_percent)})
|
||||||
|
|
||||||
|
if ram.available < 100 * MB or ram_available_percent < 5:
|
||||||
|
item["status"] = "ERROR"
|
||||||
|
item["summary"] = "diagnosis_ram_verylow"
|
||||||
|
elif ram.available < 200 * MB or ram_available_percent < 10:
|
||||||
|
item["status"] = "WARNING"
|
||||||
|
item["summary"] = "diagnosis_ram_low"
|
||||||
|
else:
|
||||||
|
item["status"] = "SUCCESS"
|
||||||
|
item["summary"] = "diagnosis_ram_ok"
|
||||||
|
yield item
|
||||||
|
|
||||||
|
#
|
||||||
|
# Swap
|
||||||
|
#
|
||||||
|
|
||||||
|
swap = psutil.swap_memory()
|
||||||
|
item = dict(meta={"test": "swap"},
|
||||||
|
data={"total": human_size(swap.total), "recommended": "512 MiB"})
|
||||||
|
if swap.total <= 1 * MB:
|
||||||
|
item["status"] = "ERROR"
|
||||||
|
item["summary"] = "diagnosis_swap_none"
|
||||||
|
elif swap.total <= 512 * MB:
|
||||||
|
item["status"] = "WARNING"
|
||||||
|
item["summary"] = "diagnosis_swap_notsomuch"
|
||||||
|
else:
|
||||||
|
item["status"] = "SUCCESS"
|
||||||
|
item["summary"] = "diagnosis_swap_ok"
|
||||||
|
yield item
|
||||||
|
|
||||||
|
# FIXME : add a check that swapiness is low if swap is on a sdcard...
|
||||||
|
|
||||||
|
#
|
||||||
|
# Disks usage
|
||||||
|
#
|
||||||
|
|
||||||
|
disk_partitions = psutil.disk_partitions()
|
||||||
|
|
||||||
|
for disk_partition in disk_partitions:
|
||||||
|
device = disk_partition.device
|
||||||
|
mountpoint = disk_partition.mountpoint
|
||||||
|
|
||||||
|
usage = psutil.disk_usage(mountpoint)
|
||||||
|
free_percent = round_(100 - usage.percent)
|
||||||
|
|
||||||
|
item = dict(meta={"test": "diskusage", "mountpoint": mountpoint},
|
||||||
|
data={"device": device, "total": human_size(usage.total), "free": human_size(usage.free), "free_percent": free_percent})
|
||||||
|
|
||||||
|
# Special checks for /boot partition because they sometimes are
|
||||||
|
# pretty small and that's kind of okay... (for example on RPi)
|
||||||
|
if mountpoint.startswith("/boot"):
|
||||||
|
if usage.free < 10 * MB or free_percent < 10:
|
||||||
|
item["status"] = "ERROR"
|
||||||
|
item["summary"] = "diagnosis_diskusage_verylow"
|
||||||
|
elif usage.free < 20 * MB or free_percent < 20:
|
||||||
|
item["status"] = "WARNING"
|
||||||
|
item["summary"] = "diagnosis_diskusage_low"
|
||||||
|
else:
|
||||||
|
item["status"] = "SUCCESS"
|
||||||
|
item["summary"] = "diagnosis_diskusage_ok"
|
||||||
|
else:
|
||||||
|
if usage.free < 1 * GB or free_percent < 5:
|
||||||
|
item["status"] = "ERROR"
|
||||||
|
item["summary"] = "diagnosis_diskusage_verylow"
|
||||||
|
elif usage.free < 2 * GB or free_percent < 10:
|
||||||
|
item["status"] = "WARNING"
|
||||||
|
item["summary"] = "diagnosis_diskusage_low"
|
||||||
|
else:
|
||||||
|
item["status"] = "SUCCESS"
|
||||||
|
item["summary"] = "diagnosis_diskusage_ok"
|
||||||
|
|
||||||
|
|
||||||
|
yield item
|
||||||
|
|
||||||
|
|
||||||
|
def human_size(bytes_):
|
||||||
|
# Adapted from https://stackoverflow.com/a/1094933
|
||||||
|
for unit in ['','ki','Mi','Gi','Ti','Pi','Ei','Zi']:
|
||||||
|
if abs(bytes_) < 1024.0:
|
||||||
|
return "%s %sB" % (round_(bytes_), unit)
|
||||||
|
bytes_ /= 1024.0
|
||||||
|
return "%s %sB" % (round_(bytes_), 'Yi')
|
||||||
|
|
||||||
|
|
||||||
|
def round_(n):
|
||||||
|
# round_(22.124) -> 22
|
||||||
|
# round_(9.45) -> 9.4
|
||||||
|
n = round(n, 1)
|
||||||
|
if n > 10:
|
||||||
|
n = int(round(n))
|
||||||
|
return n
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return SystemResourcesDiagnoser(args, env, loggers).diagnose()
|
42
data/hooks/diagnosis/70-regenconf.py
Normal file
42
data/hooks/diagnosis/70-regenconf.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from yunohost.regenconf import _get_regenconf_infos, _calculate_hash
|
||||||
|
|
||||||
|
|
||||||
|
class RegenconfDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 300
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
regenconf_modified_files = list(self.manually_modified_files())
|
||||||
|
|
||||||
|
if not regenconf_modified_files:
|
||||||
|
yield dict(meta={"test": "regenconf"},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_regenconf_allgood"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for f in regenconf_modified_files:
|
||||||
|
yield dict(meta={"test": "regenconf", "category": f['category'], "file": f['path']},
|
||||||
|
status="WARNING",
|
||||||
|
summary="diagnosis_regenconf_manually_modified",
|
||||||
|
details=["diagnosis_regenconf_manually_modified_details"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def manually_modified_files(self):
|
||||||
|
|
||||||
|
for category, infos in _get_regenconf_infos().items():
|
||||||
|
for path, hash_ in infos["conffiles"].items():
|
||||||
|
if hash_ != _calculate_hash(path):
|
||||||
|
yield {"path": path, "category": category}
|
||||||
|
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return RegenconfDiagnoser(args, env, loggers).diagnose()
|
98
data/hooks/diagnosis/90-security.py
Normal file
98
data/hooks/diagnosis/90-security.py
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from moulinette.utils.filesystem import read_json, write_to_json
|
||||||
|
|
||||||
|
|
||||||
|
class SecurityDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
cache_duration = 3600
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
"CVE-2017-5754"
|
||||||
|
|
||||||
|
if self.is_vulnerable_to_meltdown():
|
||||||
|
yield dict(meta={"test": "meltdown"},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_security_vulnerable_to_meltdown",
|
||||||
|
details=["diagnosis_security_vulnerable_to_meltdown_details"]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
yield dict(meta={},
|
||||||
|
status="SUCCESS",
|
||||||
|
summary="diagnosis_security_all_good"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def is_vulnerable_to_meltdown(self):
|
||||||
|
# meltdown CVE: https://security-tracker.debian.org/tracker/CVE-2017-5754
|
||||||
|
|
||||||
|
# We use a cache file to avoid re-running the script so many times,
|
||||||
|
# which can be expensive (up to around 5 seconds on ARM)
|
||||||
|
# and make the admin appear to be slow (c.f. the calls to diagnosis
|
||||||
|
# from the webadmin)
|
||||||
|
#
|
||||||
|
# The cache is in /tmp and shall disappear upon reboot
|
||||||
|
# *or* we compare it to dpkg.log modification time
|
||||||
|
# such that it's re-ran if there was package upgrades
|
||||||
|
# (e.g. from yunohost)
|
||||||
|
cache_file = "/tmp/yunohost-meltdown-diagnosis"
|
||||||
|
dpkg_log = "/var/log/dpkg.log"
|
||||||
|
if os.path.exists(cache_file):
|
||||||
|
if not os.path.exists(dpkg_log) or os.path.getmtime(cache_file) > os.path.getmtime(dpkg_log):
|
||||||
|
self.logger_debug("Using cached results for meltdown checker, from %s" % cache_file)
|
||||||
|
return read_json(cache_file)[0]["VULNERABLE"]
|
||||||
|
|
||||||
|
# script taken from https://github.com/speed47/spectre-meltdown-checker
|
||||||
|
# script commit id is store directly in the script
|
||||||
|
SCRIPT_PATH = "/usr/lib/moulinette/yunohost/vendor/spectre-meltdown-checker/spectre-meltdown-checker.sh"
|
||||||
|
|
||||||
|
# '--variant 3' corresponds to Meltdown
|
||||||
|
# example output from the script:
|
||||||
|
# [{"NAME":"MELTDOWN","CVE":"CVE-2017-5754","VULNERABLE":false,"INFOS":"PTI mitigates the vulnerability"}]
|
||||||
|
try:
|
||||||
|
self.logger_debug("Running meltdown vulnerability checker")
|
||||||
|
call = subprocess.Popen("bash %s --batch json --variant 3" %
|
||||||
|
SCRIPT_PATH, shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE)
|
||||||
|
|
||||||
|
# TODO / FIXME : here we are ignoring error messages ...
|
||||||
|
# in particular on RPi2 and other hardware, the script complains about
|
||||||
|
# "missing some kernel info (see -v), accuracy might be reduced"
|
||||||
|
# Dunno what to do about that but we probably don't want to harass
|
||||||
|
# users with this warning ...
|
||||||
|
output, err = call.communicate()
|
||||||
|
assert call.returncode in (0, 2, 3), "Return code: %s" % call.returncode
|
||||||
|
|
||||||
|
# If there are multiple lines, sounds like there was some messages
|
||||||
|
# in stdout that are not json >.> ... Try to get the actual json
|
||||||
|
# stuff which should be the last line
|
||||||
|
output = output.strip()
|
||||||
|
if "\n" in output:
|
||||||
|
self.logger_debug("Original meltdown checker output : %s" % output)
|
||||||
|
output = output.split("\n")[-1]
|
||||||
|
|
||||||
|
CVEs = json.loads(output)
|
||||||
|
assert len(CVEs) == 1
|
||||||
|
assert CVEs[0]["NAME"] == "MELTDOWN"
|
||||||
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
self.logger_warning("Something wrong happened when trying to diagnose Meltdown vunerability, exception: %s" % e)
|
||||||
|
raise Exception("Command output for failed meltdown check: '%s'" % output)
|
||||||
|
|
||||||
|
self.logger_debug("Writing results from meltdown checker to cache file, %s" % cache_file)
|
||||||
|
write_to_json(cache_file, CVEs)
|
||||||
|
return CVEs[0]["VULNERABLE"]
|
||||||
|
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
return SecurityDiagnoser(args, env, loggers).diagnose()
|
|
@ -5,7 +5,7 @@ if [[ $EUID -ne 0 ]]; then
|
||||||
# We need to execute this script as root, since the ldap
|
# We need to execute this script as root, since the ldap
|
||||||
# service will be shut down during the operation (and sudo
|
# service will be shut down during the operation (and sudo
|
||||||
# won't be available)
|
# won't be available)
|
||||||
sudo /bin/bash $(readlink -f $0) $1
|
/bin/bash $(readlink -f $0) $1
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
backup_dir="$1/conf/ssh"
|
backup_dir="$1/conf/ssh"
|
||||||
|
|
||||||
if [ -d /etc/ssh/ ]; then
|
if [ -d /etc/ssh/ ]; then
|
||||||
sudo cp -a $backup_dir/. /etc/ssh
|
cp -a $backup_dir/. /etc/ssh
|
||||||
sudo service ssh restart
|
service ssh restart
|
||||||
else
|
else
|
||||||
echo "SSH is not installed"
|
echo "SSH is not installed"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -9,15 +9,15 @@ service mysql status >/dev/null 2>&1 \
|
||||||
|
|
||||||
# retrieve current and new password
|
# retrieve current and new password
|
||||||
[ -f /etc/yunohost/mysql ] \
|
[ -f /etc/yunohost/mysql ] \
|
||||||
&& curr_pwd=$(sudo cat /etc/yunohost/mysql)
|
&& curr_pwd=$(cat /etc/yunohost/mysql)
|
||||||
new_pwd=$(sudo cat "${backup_dir}/root_pwd" || sudo cat "${backup_dir}/mysql")
|
new_pwd=$(cat "${backup_dir}/root_pwd" || cat "${backup_dir}/mysql")
|
||||||
[ -z "$curr_pwd" ] && curr_pwd="yunohost"
|
[ -z "$curr_pwd" ] && curr_pwd="yunohost"
|
||||||
[ -z "$new_pwd" ] && {
|
[ -z "$new_pwd" ] && {
|
||||||
new_pwd=$(ynh_string_random 10)
|
new_pwd=$(ynh_string_random 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
# attempt to change it
|
# attempt to change it
|
||||||
sudo mysqladmin -s -u root -p"$curr_pwd" password "$new_pwd" || {
|
mysqladmin -s -u root -p"$curr_pwd" password "$new_pwd" || {
|
||||||
|
|
||||||
echo "It seems that you have already configured MySQL." \
|
echo "It seems that you have already configured MySQL." \
|
||||||
"YunoHost needs to have a root access to MySQL to runs its" \
|
"YunoHost needs to have a root access to MySQL to runs its" \
|
||||||
|
@ -25,18 +25,18 @@ sudo mysqladmin -s -u root -p"$curr_pwd" password "$new_pwd" || {
|
||||||
"You can find this new password in /etc/yunohost/mysql." >&2
|
"You can find this new password in /etc/yunohost/mysql." >&2
|
||||||
|
|
||||||
# set new password with debconf
|
# set new password with debconf
|
||||||
sudo debconf-set-selections << EOF
|
debconf-set-selections << EOF
|
||||||
$MYSQL_PKG mysql-server/root_password password $new_pwd
|
$MYSQL_PKG mysql-server/root_password password $new_pwd
|
||||||
$MYSQL_PKG mysql-server/root_password_again password $new_pwd
|
$MYSQL_PKG mysql-server/root_password_again password $new_pwd
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# reconfigure Debian package
|
# reconfigure Debian package
|
||||||
sudo dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1
|
dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
# store new root password
|
# store new root password
|
||||||
echo "$new_pwd" | sudo tee /etc/yunohost/mysql
|
echo "$new_pwd" | tee /etc/yunohost/mysql
|
||||||
sudo chmod 400 /etc/yunohost/mysql
|
chmod 400 /etc/yunohost/mysql
|
||||||
|
|
||||||
# reload the grant tables
|
# reload the grant tables
|
||||||
sudo mysqladmin -s -u root -p"$new_pwd" reload
|
mysqladmin -s -u root -p"$new_pwd" reload
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
backup_dir="$1/conf/ssowat"
|
backup_dir="$1/conf/ssowat"
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /etc/ssowat
|
cp -a $backup_dir/. /etc/ssowat
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
backup_dir="$1/data/home"
|
backup_dir="$1/data/home"
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /home
|
cp -a $backup_dir/. /home
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
backup_dir="$1/conf/ynh/firewall"
|
backup_dir="$1/conf/ynh/firewall"
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /etc/yunohost
|
cp -a $backup_dir/. /etc/yunohost
|
||||||
sudo yunohost firewall reload
|
yunohost firewall reload
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
backup_dir="$1/conf/ynh/certs"
|
backup_dir="$1/conf/ynh/certs"
|
||||||
|
|
||||||
sudo mkdir -p /etc/yunohost/certs/
|
mkdir -p /etc/yunohost/certs/
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /etc/yunohost/certs/
|
cp -a $backup_dir/. /etc/yunohost/certs/
|
||||||
sudo yunohost app ssowatconf
|
service nginx reload
|
||||||
sudo service nginx reload
|
service metronome reload
|
||||||
sudo service metronome reload
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
backup_dir="$1/data/mail"
|
backup_dir="$1/data/mail"
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /var/mail/ || echo 'No mail found'
|
cp -a $backup_dir/. /var/mail/ || echo 'No mail found'
|
||||||
sudo chown -R vmail:mail /var/mail/
|
chown -R vmail:mail /var/mail/
|
||||||
|
|
||||||
# Restart services to use migrated certs
|
# Restart services to use migrated certs
|
||||||
sudo service postfix restart
|
service postfix restart
|
||||||
sudo service dovecot restart
|
service dovecot restart
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
backup_dir="$1/conf/xmpp"
|
backup_dir="$1/conf/xmpp"
|
||||||
|
|
||||||
sudo cp -a $backup_dir/etc/. /etc/metronome
|
cp -a $backup_dir/etc/. /etc/metronome
|
||||||
sudo cp -a $backup_dir/var/. /var/lib/metronome
|
cp -a $backup_dir/var/. /var/lib/metronome
|
||||||
|
|
||||||
# Restart to apply new conf and certs
|
# Restart to apply new conf and certs
|
||||||
sudo service metronome restart
|
service metronome restart
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
backup_dir="$1/conf/nginx"
|
backup_dir="$1/conf/nginx"
|
||||||
|
|
||||||
# Copy all conf except apps specific conf located in DOMAIN.d
|
# Copy all conf except apps specific conf located in DOMAIN.d
|
||||||
sudo find $backup_dir/ -mindepth 1 -maxdepth 1 -name '*.d' -or -exec sudo cp -a {} /etc/nginx/conf.d/ \;
|
find $backup_dir/ -mindepth 1 -maxdepth 1 -name '*.d' -or -exec cp -a {} /etc/nginx/conf.d/ \;
|
||||||
|
|
||||||
# Restart to use new conf and certs
|
# Restart to use new conf and certs
|
||||||
sudo service nginx restart
|
service nginx restart
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
backup_dir="$1/conf/cron"
|
backup_dir="$1/conf/cron"
|
||||||
|
|
||||||
sudo cp -a $backup_dir/. /etc/cron.d
|
cp -a $backup_dir/. /etc/cron.d
|
||||||
|
|
||||||
# Restart just in case
|
# Restart just in case
|
||||||
sudo service cron restart
|
service cron restart
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
backup_dir="$1/conf/ynh"
|
backup_dir="$1/conf/ynh"
|
||||||
|
|
||||||
sudo cp -a "${backup_dir}/current_host" /etc/yunohost/current_host
|
cp -a "${backup_dir}/current_host" /etc/yunohost/current_host
|
||||||
|
|
184
data/other/dnsbl_list.yml
Normal file
184
data/other/dnsbl_list.yml
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
# Used by GAFAM
|
||||||
|
- name: Spamhaus ZEN
|
||||||
|
dns_server: zen.spamhaus.org
|
||||||
|
website: https://www.spamhaus.org/zen/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: true
|
||||||
|
domain: false
|
||||||
|
- name: Barracuda Reputation Block List
|
||||||
|
dns_server: b.barracudacentral.org
|
||||||
|
website: https://barracudacentral.org/rbl/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: Hostkarma
|
||||||
|
dns_server: hostkarma.junkemailfilter.com
|
||||||
|
website: https://ipadmin.junkemailfilter.com/remove.php
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: ImproWare IP based spamlist
|
||||||
|
dns_server: spamrbl.imp.ch
|
||||||
|
website: https://antispam.imp.ch/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: ImproWare IP based wormlist
|
||||||
|
dns_server: wormrbl.imp.ch
|
||||||
|
website: https://antispam.imp.ch/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: Backscatterer.org
|
||||||
|
dns_server: ips.backscatterer.org
|
||||||
|
website: http://www.backscatterer.org/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: inps.de
|
||||||
|
dns_server: dnsbl.inps.de
|
||||||
|
website: http://dnsbl.inps.de/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: LASHBACK
|
||||||
|
dns_server: ubl.unsubscore.com
|
||||||
|
website: https://blacklist.lashback.com/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: Mailspike.org
|
||||||
|
dns_server: bl.mailspike.net
|
||||||
|
website: http://www.mailspike.net/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: NiX Spam
|
||||||
|
dns_server: ix.dnsbl.manitu.net
|
||||||
|
website: http://www.dnsbl.manitu.net/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: REDHAWK
|
||||||
|
dns_server: access.redhawk.org
|
||||||
|
website: https://www.redhawk.org/SpamHawk/query.php
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: SORBS Open SMTP relays
|
||||||
|
dns_server: smtp.dnsbl.sorbs.net
|
||||||
|
website: http://www.sorbs.net/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: SORBS Spamhost (last 28 days)
|
||||||
|
dns_server: recent.spam.dnsbl.sorbs.net
|
||||||
|
website: http://www.sorbs.net/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: SORBS Spamhost (last 48 hours)
|
||||||
|
dns_server: new.spam.dnsbl.sorbs.net
|
||||||
|
website: http://www.sorbs.net/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: SpamCop Blocking List
|
||||||
|
dns_server: bl.spamcop.net
|
||||||
|
website: https://www.spamcop.net/bl.shtml
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: Spam Eating Monkey SEM-BACKSCATTER
|
||||||
|
dns_server: backscatter.spameatingmonkey.net
|
||||||
|
website: https://spameatingmonkey.com/services
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: Spam Eating Monkey SEM-BLACK
|
||||||
|
dns_server: bl.spameatingmonkey.net
|
||||||
|
website: https://spameatingmonkey.com/services
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: Spam Eating Monkey SEM-IPV6BL
|
||||||
|
dns_server: bl.ipv6.spameatingmonkey.net
|
||||||
|
website: https://spameatingmonkey.com/services
|
||||||
|
ipv4: false
|
||||||
|
ipv6: true
|
||||||
|
domain: false
|
||||||
|
- name: SpamRATS! all
|
||||||
|
dns_server: all.spamrats.com
|
||||||
|
website: http://www.spamrats.com/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: PSBL (Passive Spam Block List)
|
||||||
|
dns_server: psbl.surriel.com
|
||||||
|
website: http://psbl.surriel.com/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: SWINOG
|
||||||
|
dns_server: dnsrbl.swinog.ch
|
||||||
|
website: https://antispam.imp.ch/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: GBUdb Truncate
|
||||||
|
dns_server: truncate.gbudb.net
|
||||||
|
website: http://www.gbudb.com/truncate/index.jsp
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: Weighted Private Block List
|
||||||
|
dns_server: db.wpbl.info
|
||||||
|
website: http://www.wpbl.info/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
# Used by GAFAM
|
||||||
|
- name: Composite Blocking List
|
||||||
|
dns_server: cbl.abuseat.org
|
||||||
|
website: cbl.abuseat.org
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
# Used by GAFAM
|
||||||
|
- name: SenderScore Blacklist
|
||||||
|
dns_server: bl.score.senderscore.com
|
||||||
|
website: https://senderscore.com
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
- name: Invaluement
|
||||||
|
dns_server: sip.invaluement.com
|
||||||
|
website: https://www.invaluement.com/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: false
|
||||||
|
domain: false
|
||||||
|
# Added cause it supports IPv6
|
||||||
|
- name: AntiCaptcha.NET IPv6
|
||||||
|
dns_server: dnsbl6.anticaptcha.net
|
||||||
|
website: http://anticaptcha.net/
|
||||||
|
ipv4: false
|
||||||
|
ipv6: true
|
||||||
|
domain: false
|
||||||
|
- name: SPFBL.net RBL
|
||||||
|
dns_server: dnsbl.spfbl.net
|
||||||
|
website: https://spfbl.net/en/dnsbl/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: true
|
||||||
|
domain: true
|
||||||
|
- name: Suomispam Blacklist
|
||||||
|
dns_server: bl.suomispam.net
|
||||||
|
website: http://suomispam.net/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: true
|
||||||
|
domain: false
|
||||||
|
- name: NordSpam
|
||||||
|
dns_server: bl.nordspam.com
|
||||||
|
website: https://www.nordspam.com/
|
||||||
|
ipv4: true
|
||||||
|
ipv6: true
|
||||||
|
domain: false
|
|
@ -57,18 +57,24 @@ children:
|
||||||
objectClass:
|
objectClass:
|
||||||
- posixGroup
|
- posixGroup
|
||||||
- groupOfNamesYnh
|
- groupOfNamesYnh
|
||||||
|
cn=visitors,ou=groups:
|
||||||
|
cn: visitors
|
||||||
|
gidNumber: "4003"
|
||||||
|
objectClass:
|
||||||
|
- posixGroup
|
||||||
|
- groupOfNamesYnh
|
||||||
|
|
||||||
depends_children:
|
depends_children:
|
||||||
cn=main.mail,ou=permission:
|
cn=mail.main,ou=permission:
|
||||||
cn: main.mail
|
cn: mail.main
|
||||||
gidNumber: "5001"
|
gidNumber: "5001"
|
||||||
objectClass:
|
objectClass:
|
||||||
- posixGroup
|
- posixGroup
|
||||||
- permissionYnh
|
- permissionYnh
|
||||||
groupPermission:
|
groupPermission:
|
||||||
- "cn=all_users,ou=groups,dc=yunohost,dc=org"
|
- "cn=all_users,ou=groups,dc=yunohost,dc=org"
|
||||||
cn=main.metronome,ou=permission:
|
cn=xmpp.main,ou=permission:
|
||||||
cn: main.metronome
|
cn: xmpp.main
|
||||||
gidNumber: "5002"
|
gidNumber: "5002"
|
||||||
objectClass:
|
objectClass:
|
||||||
- posixGroup
|
- posixGroup
|
||||||
|
|
|
@ -32,7 +32,6 @@ nameserver 85.214.20.141
|
||||||
nameserver 195.160.173.53
|
nameserver 195.160.173.53
|
||||||
# (DE) AS250
|
# (DE) AS250
|
||||||
nameserver 194.150.168.168
|
nameserver 194.150.168.168
|
||||||
nameserver 2001:4ce8::53
|
|
||||||
# (DE) Ideal-Hosting
|
# (DE) Ideal-Hosting
|
||||||
nameserver 84.200.69.80
|
nameserver 84.200.69.80
|
||||||
nameserver 2001:1608:10:25::1c04:b12f
|
nameserver 2001:1608:10:25::1c04:b12f
|
||||||
|
|
|
@ -3,7 +3,7 @@ auth_bind = yes
|
||||||
ldap_version = 3
|
ldap_version = 3
|
||||||
base = ou=users,dc=yunohost,dc=org
|
base = ou=users,dc=yunohost,dc=org
|
||||||
user_attrs = uidNumber=500,gidNumber=8,mailuserquota=quota_rule=*:bytes=%$
|
user_attrs = uidNumber=500,gidNumber=8,mailuserquota=quota_rule=*:bytes=%$
|
||||||
user_filter = (&(objectClass=inetOrgPerson)(uid=%n)(permission=cn=main.mail,ou=permission,dc=yunohost,dc=org))
|
user_filter = (&(objectClass=inetOrgPerson)(uid=%n)(permission=cn=mail.main,ou=permission,dc=yunohost,dc=org))
|
||||||
pass_filter = (&(objectClass=inetOrgPerson)(uid=%n)(permission=cn=main.mail,ou=permission,dc=yunohost,dc=org))
|
pass_filter = (&(objectClass=inetOrgPerson)(uid=%n)(permission=cn=mail.main,ou=permission,dc=yunohost,dc=org))
|
||||||
default_pass_scheme = SSHA
|
default_pass_scheme = SSHA
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,29 @@ mail_home = /var/mail/%n
|
||||||
mail_location = maildir:/var/mail/%n
|
mail_location = maildir:/var/mail/%n
|
||||||
mail_uid = 500
|
mail_uid = 500
|
||||||
|
|
||||||
protocols = imap sieve
|
protocols = imap sieve {% if pop3_enabled == "True" %}pop3{% endif %}
|
||||||
|
|
||||||
mail_plugins = $mail_plugins quota
|
mail_plugins = $mail_plugins quota
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# generated 2020-04-03, Mozilla Guideline v5.4, Dovecot 2.2.27, OpenSSL 1.1.0l, intermediate configuration
|
||||||
|
# https://ssl-config.mozilla.org/#server=dovecot&version=2.2.27&config=intermediate&openssl=1.1.0l&guideline=5.4
|
||||||
|
|
||||||
|
ssl = required
|
||||||
|
|
||||||
ssl = yes
|
|
||||||
ssl_cert = </etc/yunohost/certs/{{ main_domain }}/crt.pem
|
ssl_cert = </etc/yunohost/certs/{{ main_domain }}/crt.pem
|
||||||
ssl_key = </etc/yunohost/certs/{{ main_domain }}/key.pem
|
ssl_key = </etc/yunohost/certs/{{ main_domain }}/key.pem
|
||||||
ssl_protocols = !SSLv3
|
|
||||||
|
ssl_dh_parameters_length = 2048
|
||||||
|
|
||||||
|
# intermediate configuration
|
||||||
|
ssl_protocols = TLSv1.2
|
||||||
|
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
||||||
|
ssl_prefer_server_ciphers = no
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
passdb {
|
passdb {
|
||||||
args = /etc/dovecot/dovecot-ldap.conf
|
args = /etc/dovecot/dovecot-ldap.conf
|
||||||
|
|
|
@ -63,7 +63,7 @@ bantime = 600
|
||||||
findtime = 600
|
findtime = 600
|
||||||
|
|
||||||
# "maxretry" is the number of failures before a host get banned.
|
# "maxretry" is the number of failures before a host get banned.
|
||||||
maxretry = 5
|
maxretry = 10
|
||||||
|
|
||||||
# "backend" specifies the backend used to get files modification.
|
# "backend" specifies the backend used to get files modification.
|
||||||
# Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".
|
# Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".
|
||||||
|
|
|
@ -29,4 +29,3 @@ protocol = tcp
|
||||||
filter = yunohost
|
filter = yunohost
|
||||||
logpath = /var/log/nginx/*error.log
|
logpath = /var/log/nginx/*error.log
|
||||||
/var/log/nginx/*access.log
|
/var/log/nginx/*access.log
|
||||||
maxretry = 10
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
# Default is to launch glances with '-s' option.
|
|
||||||
DAEMON_ARGS="-s -B 127.0.0.1"
|
|
||||||
|
|
||||||
# Change to 'true' to have glances running at startup
|
|
||||||
RUN="true"
|
|
|
@ -1,4 +1,5 @@
|
||||||
VirtualHost "{{ domain }}"
|
VirtualHost "{{ domain }}"
|
||||||
|
enable = true
|
||||||
ssl = {
|
ssl = {
|
||||||
key = "/etc/yunohost/certs/{{ domain }}/key.pem";
|
key = "/etc/yunohost/certs/{{ domain }}/key.pem";
|
||||||
certificate = "/etc/yunohost/certs/{{ domain }}/crt.pem";
|
certificate = "/etc/yunohost/certs/{{ domain }}/crt.pem";
|
||||||
|
@ -8,8 +9,63 @@ VirtualHost "{{ domain }}"
|
||||||
hostname = "localhost",
|
hostname = "localhost",
|
||||||
user = {
|
user = {
|
||||||
basedn = "ou=users,dc=yunohost,dc=org",
|
basedn = "ou=users,dc=yunohost,dc=org",
|
||||||
filter = "(&(objectClass=posixAccount)(mail=*@{{ domain }})(permission=cn=main.metronome,ou=permission,dc=yunohost,dc=org))",
|
filter = "(&(objectClass=posixAccount)(mail=*@{{ domain }})(permission=cn=xmpp.main,ou=permission,dc=yunohost,dc=org))",
|
||||||
usernamefield = "mail",
|
usernamefield = "mail",
|
||||||
namefield = "cn",
|
namefield = "cn",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Discovery items
|
||||||
|
disco_items = {
|
||||||
|
{ "muc.{{ domain }}" },
|
||||||
|
{ "pubsub.{{ domain }}" },
|
||||||
|
{ "jabber.{{ domain }}" },
|
||||||
|
{ "vjud.{{ domain }}" },
|
||||||
|
{ "xmpp-upload.{{ domain }}" },
|
||||||
|
};
|
||||||
|
|
||||||
|
-- contact_info = {
|
||||||
|
-- abuse = { "mailto:abuse@{{ domain }}", "xmpp:admin@{{ domain }}" };
|
||||||
|
-- admin = { "mailto:root@{{ domain }}", "xmpp:admin@{{ domain }}" };
|
||||||
|
-- };
|
||||||
|
|
||||||
|
------ Components ------
|
||||||
|
-- You can specify components to add hosts that provide special services,
|
||||||
|
-- like multi-user conferences, and transports.
|
||||||
|
|
||||||
|
---Set up a MUC (multi-user chat) room server
|
||||||
|
Component "muc.{{ domain }}" "muc"
|
||||||
|
name = "{{ domain }} Chatrooms"
|
||||||
|
|
||||||
|
modules_enabled = {
|
||||||
|
"muc_limits";
|
||||||
|
"muc_log";
|
||||||
|
"muc_log_mam";
|
||||||
|
"muc_log_http";
|
||||||
|
"muc_vcard";
|
||||||
|
}
|
||||||
|
|
||||||
|
muc_event_rate = 0.5
|
||||||
|
muc_burst_factor = 10
|
||||||
|
|
||||||
|
---Set up a PubSub server
|
||||||
|
Component "pubsub.{{ domain }}" "pubsub"
|
||||||
|
name = "{{ domain }} Publish/Subscribe"
|
||||||
|
|
||||||
|
unrestricted_node_creation = true -- Anyone can create a PubSub node (from any server)
|
||||||
|
|
||||||
|
---Set up a HTTP Upload service
|
||||||
|
Component "xmpp-upload.{{ domain }}" "http_upload"
|
||||||
|
name = "{{ domain }} Sharing Service"
|
||||||
|
|
||||||
|
http_file_path = "/var/xmpp-upload/{{ domain }}/upload"
|
||||||
|
http_external_url = "https://xmpp-upload.{{ domain }}:443"
|
||||||
|
http_file_base_path = "/upload"
|
||||||
|
http_file_size_limit = 6*1024*1024
|
||||||
|
http_file_quota = 60*1024*1024
|
||||||
|
http_upload_file_size_limit = 100 * 1024 * 1024 -- bytes
|
||||||
|
http_upload_quota = 10 * 1024 * 1024 * 1024 -- bytes
|
||||||
|
|
||||||
|
---Set up a VJUD service
|
||||||
|
Component "vjud.{{ domain }}" "vjud"
|
||||||
|
vjud_disco_name = "{{ domain }} User Directory"
|
||||||
|
|
|
@ -81,14 +81,6 @@ http_interfaces = { "127.0.0.1", "::1" }
|
||||||
-- Enable IPv6
|
-- Enable IPv6
|
||||||
use_ipv6 = true
|
use_ipv6 = true
|
||||||
|
|
||||||
-- Discovery items
|
|
||||||
disco_items = {
|
|
||||||
{ "muc.{{ main_domain }}" },
|
|
||||||
{ "pubsub.{{ main_domain }}" },
|
|
||||||
{ "upload.{{ main_domain }}" },
|
|
||||||
{ "vjud.{{ main_domain }}" }
|
|
||||||
};
|
|
||||||
|
|
||||||
-- BOSH configuration (mod_bosh)
|
-- BOSH configuration (mod_bosh)
|
||||||
consider_bosh_secure = true
|
consider_bosh_secure = true
|
||||||
cross_domain_bosh = true
|
cross_domain_bosh = true
|
||||||
|
@ -119,40 +111,6 @@ log = {
|
||||||
Component "localhost" "http"
|
Component "localhost" "http"
|
||||||
modules_enabled = { "bosh" }
|
modules_enabled = { "bosh" }
|
||||||
|
|
||||||
---Set up a MUC (multi-user chat) room server
|
|
||||||
Component "muc.{{ main_domain }}" "muc"
|
|
||||||
name = "{{ main_domain }} Chatrooms"
|
|
||||||
|
|
||||||
modules_enabled = {
|
|
||||||
"muc_limits";
|
|
||||||
"muc_log";
|
|
||||||
"muc_log_mam";
|
|
||||||
"muc_log_http";
|
|
||||||
"muc_vcard";
|
|
||||||
}
|
|
||||||
|
|
||||||
muc_event_rate = 0.5
|
|
||||||
muc_burst_factor = 10
|
|
||||||
|
|
||||||
---Set up a PubSub server
|
|
||||||
Component "pubsub.{{ main_domain }}" "pubsub"
|
|
||||||
name = "{{ main_domain }} Publish/Subscribe"
|
|
||||||
|
|
||||||
unrestricted_node_creation = true -- Anyone can create a PubSub node (from any server)
|
|
||||||
|
|
||||||
---Set up a HTTP Upload service
|
|
||||||
Component "upload.{{ main_domain }}" "http_upload"
|
|
||||||
name = "{{ main_domain }} Sharing Service"
|
|
||||||
|
|
||||||
http_file_size_limit = 6*1024*1024
|
|
||||||
http_file_quota = 60*1024*1024
|
|
||||||
|
|
||||||
|
|
||||||
---Set up a VJUD service
|
|
||||||
Component "vjud.{{ main_domain }}" "vjud"
|
|
||||||
ud_disco_name = "{{ main_domain }} User Directory"
|
|
||||||
|
|
||||||
|
|
||||||
----------- Virtual hosts -----------
|
----------- Virtual hosts -----------
|
||||||
-- You need to add a VirtualHost entry for each domain you wish Metronome to serve.
|
-- You need to add a VirtualHost entry for each domain you wish Metronome to serve.
|
||||||
-- Settings under each VirtualHost entry apply *only* to that host.
|
-- Settings under each VirtualHost entry apply *only* to that host.
|
||||||
|
|
5
data/templates/nginx/plain/acme-challenge.conf.inc
Normal file
5
data/templates/nginx/plain/acme-challenge.conf.inc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
location ^~ '/.well-known/acme-challenge/'
|
||||||
|
{
|
||||||
|
default_type "text/plain";
|
||||||
|
alias /tmp/acme-challenge-public/;
|
||||||
|
}
|
|
@ -4,5 +4,5 @@ sub_filter_once on;
|
||||||
# Apply to other mime types than text/html
|
# Apply to other mime types than text/html
|
||||||
sub_filter_types application/xhtml+xml;
|
sub_filter_types application/xhtml+xml;
|
||||||
# Prevent YunoHost panel files from being blocked by specific app rules
|
# Prevent YunoHost panel files from being blocked by specific app rules
|
||||||
location ~ (ynh_portal.js|ynh_overlay.css|ynh_userinfo.json) {
|
location ~ (ynh_portal.js|ynh_overlay.css|ynh_userinfo.json|ynhtheme/custom_portal.js|ynhtheme/custom_overlay.css) {
|
||||||
}
|
}
|
||||||
|
|
34
data/templates/nginx/security.conf.inc
Normal file
34
data/templates/nginx/security.conf.inc
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
ssl_session_cache shared:SSL:50m; # about 200000 sessions
|
||||||
|
ssl_session_tickets off;
|
||||||
|
|
||||||
|
# nginx 1.10 in stretch doesn't support TLS1.3 and Mozilla doesn't have any
|
||||||
|
# "modern" config recommendation with it.
|
||||||
|
# So until buster the modern conf is same as intermediate
|
||||||
|
{% if compatibility == "modern" %} {% else %} {% endif %}
|
||||||
|
|
||||||
|
# Ciphers with intermediate compatibility
|
||||||
|
# generated 2020-04-03, Mozilla Guideline v5.4, nginx 1.10.3, OpenSSL 1.1.0l, intermediate configuration
|
||||||
|
# https://ssl-config.mozilla.org/#server=nginx&version=1.10.3&config=intermediate&openssl=1.1.0l&guideline=5.4
|
||||||
|
ssl_protocols TLSv1.2;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
|
||||||
|
# Uncomment the following directive after DH generation
|
||||||
|
# > openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048
|
||||||
|
#ssl_dhparam /etc/ssl/private/dh2048.pem;
|
||||||
|
|
||||||
|
# Follows the Web Security Directives from the Mozilla Dev Lab and the Mozilla Obervatory + Partners
|
||||||
|
# https://wiki.mozilla.org/Security/Guidelines/Web_Security
|
||||||
|
# https://observatory.mozilla.org/
|
||||||
|
more_set_headers "Content-Security-Policy : upgrade-insecure-requests";
|
||||||
|
more_set_headers "Content-Security-Policy-Report-Only : default-src https: data: 'unsafe-inline' 'unsafe-eval'";
|
||||||
|
more_set_headers "X-Content-Type-Options : nosniff";
|
||||||
|
more_set_headers "X-XSS-Protection : 1; mode=block";
|
||||||
|
more_set_headers "X-Download-Options : noopen";
|
||||||
|
more_set_headers "X-Permitted-Cross-Domain-Policies : none";
|
||||||
|
more_set_headers "X-Frame-Options : SAMEORIGIN";
|
||||||
|
|
||||||
|
# Disable gzip to protect against BREACH
|
||||||
|
# Read https://trac.nginx.org/nginx/ticket/1720 (text/html cannot be disabled!)
|
||||||
|
gzip off;
|
|
@ -6,17 +6,23 @@ map $http_upgrade $connection_upgrade {
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name {{ domain }};
|
server_name {{ domain }} xmpp-upload.{{ domain }};
|
||||||
|
|
||||||
access_by_lua_file /usr/share/ssowat/access.lua;
|
access_by_lua_file /usr/share/ssowat/access.lua;
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/acme-challenge.conf.inc;
|
||||||
|
|
||||||
include /etc/nginx/conf.d/{{ domain }}.d/*.conf;
|
include /etc/nginx/conf.d/{{ domain }}.d/*.conf;
|
||||||
|
|
||||||
location /yunohost/admin {
|
location /yunohost/admin {
|
||||||
return 301 https://$http_host$request_uri;
|
return 301 https://$http_host$request_uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /.well-known/autoconfig/mail/ {
|
location ^~ '/.well-known/ynh-diagnosis/' {
|
||||||
|
alias /tmp/.well-known/ynh-diagnosis/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ '/.well-known/autoconfig/mail/' {
|
||||||
alias /var/www/.well-known/{{ domain }}/autoconfig/mail/;
|
alias /var/www/.well-known/{{ domain }}/autoconfig/mail/;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,47 +35,14 @@ server {
|
||||||
listen [::]:443 ssl http2;
|
listen [::]:443 ssl http2;
|
||||||
server_name {{ domain }};
|
server_name {{ domain }};
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/security.conf.inc;
|
||||||
|
|
||||||
ssl_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
ssl_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
||||||
ssl_certificate_key /etc/yunohost/certs/{{ domain }}/key.pem;
|
ssl_certificate_key /etc/yunohost/certs/{{ domain }}/key.pem;
|
||||||
ssl_session_timeout 5m;
|
|
||||||
ssl_session_cache shared:SSL:50m;
|
|
||||||
|
|
||||||
{% if compatibility == "modern" %}
|
|
||||||
# Ciphers with modern compatibility
|
|
||||||
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.6.2&openssl=1.0.1t&hsts=yes&profile=modern
|
|
||||||
# The following configuration use modern ciphers, but remove compatibility with some old clients (android < 5.0, Internet Explorer < 10, ...)
|
|
||||||
ssl_protocols TLSv1.2;
|
|
||||||
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
{% else %}
|
|
||||||
# As suggested by Mozilla : https://wiki.mozilla.org/Security/Server_Side_TLS and https://en.wikipedia.org/wiki/Curve25519
|
|
||||||
ssl_ecdh_curve secp521r1:secp384r1:prime256v1;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
# Ciphers with intermediate compatibility
|
|
||||||
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.6.2&openssl=1.0.1t&hsts=yes&profile=intermediate
|
|
||||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
|
||||||
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
|
|
||||||
|
|
||||||
# Uncomment the following directive after DH generation
|
|
||||||
# > openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048
|
|
||||||
#ssl_dhparam /etc/ssl/private/dh2048.pem;
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# Follows the Web Security Directives from the Mozilla Dev Lab and the Mozilla Obervatory + Partners
|
|
||||||
# https://wiki.mozilla.org/Security/Guidelines/Web_Security
|
|
||||||
# https://observatory.mozilla.org/
|
|
||||||
{% if domain_cert_ca != "Self-signed" %}
|
{% if domain_cert_ca != "Self-signed" %}
|
||||||
more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload";
|
more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload";
|
||||||
{% endif %}
|
{% endif %}
|
||||||
more_set_headers "Content-Security-Policy : upgrade-insecure-requests";
|
|
||||||
more_set_headers "Content-Security-Policy-Report-Only : default-src https: data: 'unsafe-inline' 'unsafe-eval'";
|
|
||||||
more_set_headers "X-Content-Type-Options : nosniff";
|
|
||||||
more_set_headers "X-XSS-Protection : 1; mode=block";
|
|
||||||
more_set_headers "X-Download-Options : noopen";
|
|
||||||
more_set_headers "X-Permitted-Cross-Domain-Policies : none";
|
|
||||||
more_set_headers "X-Frame-Options : SAMEORIGIN";
|
|
||||||
|
|
||||||
{% if domain_cert_ca == "Let's Encrypt" %}
|
{% if domain_cert_ca == "Let's Encrypt" %}
|
||||||
# OCSP settings
|
# OCSP settings
|
||||||
ssl_stapling on;
|
ssl_stapling on;
|
||||||
|
@ -79,9 +52,9 @@ server {
|
||||||
resolver_timeout 5s;
|
resolver_timeout 5s;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# Disable gzip to protect against BREACH
|
location ^~ '/.well-known/autoconfig/mail/' {
|
||||||
# Read https://trac.nginx.org/nginx/ticket/1720 (text/html cannot be disabled!)
|
alias /var/www/.well-known/{{ domain }}/autoconfig/mail/;
|
||||||
gzip off;
|
}
|
||||||
|
|
||||||
access_by_lua_file /usr/share/ssowat/access.lua;
|
access_by_lua_file /usr/share/ssowat/access.lua;
|
||||||
|
|
||||||
|
@ -93,3 +66,46 @@ server {
|
||||||
access_log /var/log/nginx/{{ domain }}-access.log;
|
access_log /var/log/nginx/{{ domain }}-access.log;
|
||||||
error_log /var/log/nginx/{{ domain }}-error.log;
|
error_log /var/log/nginx/{{ domain }}-error.log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# vhost dedicated to XMPP http_upload
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
server_name xmpp-upload.{{ domain }};
|
||||||
|
root /dev/null;
|
||||||
|
|
||||||
|
location /upload/ {
|
||||||
|
alias /var/xmpp-upload/{{ domain }}/upload/;
|
||||||
|
# Pass all requests to metronome, except for GET and HEAD requests.
|
||||||
|
limit_except GET HEAD {
|
||||||
|
proxy_pass http://localhost:5290;
|
||||||
|
}
|
||||||
|
|
||||||
|
include proxy_params;
|
||||||
|
add_header 'Access-Control-Allow-Origin' '*';
|
||||||
|
add_header 'Access-Control-Allow-Methods' 'HEAD, GET, PUT, OPTIONS';
|
||||||
|
add_header 'Access-Control-Allow-Headers' 'Authorization';
|
||||||
|
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||||
|
client_max_body_size 105M; # Choose a value a bit higher than the max upload configured in XMPP server
|
||||||
|
}
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/security.conf.inc;
|
||||||
|
|
||||||
|
ssl_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
||||||
|
ssl_certificate_key /etc/yunohost/certs/{{ domain }}/key.pem;
|
||||||
|
|
||||||
|
{% if domain_cert_ca != "Self-signed" %}
|
||||||
|
more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload";
|
||||||
|
{% endif %}
|
||||||
|
{% if domain_cert_ca == "Let's Encrypt" %}
|
||||||
|
# OCSP settings
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
||||||
|
ssl_trusted_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
||||||
|
resolver 127.0.0.1 127.0.1.1 valid=300s;
|
||||||
|
resolver_timeout 5s;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
access_log /var/log/nginx/xmpp-upload.{{ domain }}-access.log;
|
||||||
|
error_log /var/log/nginx/xmpp-upload.{{ domain }}-error.log;
|
||||||
|
}
|
||||||
|
|
|
@ -15,48 +15,14 @@ server {
|
||||||
listen 443 ssl http2 default_server;
|
listen 443 ssl http2 default_server;
|
||||||
listen [::]:443 ssl http2 default_server;
|
listen [::]:443 ssl http2 default_server;
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/security.conf.inc;
|
||||||
|
|
||||||
ssl_certificate /etc/yunohost/certs/yunohost.org/crt.pem;
|
ssl_certificate /etc/yunohost/certs/yunohost.org/crt.pem;
|
||||||
ssl_certificate_key /etc/yunohost/certs/yunohost.org/key.pem;
|
ssl_certificate_key /etc/yunohost/certs/yunohost.org/key.pem;
|
||||||
ssl_session_timeout 5m;
|
|
||||||
ssl_session_cache shared:SSL:50m;
|
|
||||||
|
|
||||||
{% if compatibility == "modern" %}
|
|
||||||
# Ciphers with modern compatibility
|
|
||||||
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.6.2&openssl=1.0.1t&hsts=yes&profile=modern
|
|
||||||
# Uncomment the following to use modern ciphers, but remove compatibility with some old clients (android < 5.0, Internet Explorer < 10, ...)
|
|
||||||
ssl_protocols TLSv1.2;
|
|
||||||
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
{% else %}
|
|
||||||
# As suggested by Mozilla : https://wiki.mozilla.org/Security/Server_Side_TLS and https://en.wikipedia.org/wiki/Curve25519
|
|
||||||
ssl_ecdh_curve secp521r1:secp384r1:prime256v1;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
# Ciphers with intermediate compatibility
|
|
||||||
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.6.2&openssl=1.0.1t&hsts=yes&profile=intermediate
|
|
||||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
|
||||||
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
|
|
||||||
|
|
||||||
# Uncomment the following directive after DH generation
|
|
||||||
# > openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048
|
|
||||||
#ssl_dhparam /etc/ssl/private/dh2048.pem;
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# Follows the Web Security Directives from the Mozilla Dev Lab and the Mozilla Obervatory + Partners
|
|
||||||
# https://wiki.mozilla.org/Security/Guidelines/Web_Security
|
|
||||||
# https://observatory.mozilla.org/
|
|
||||||
more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload";
|
more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload";
|
||||||
more_set_headers "Referrer-Policy : 'same-origin'";
|
more_set_headers "Referrer-Policy : 'same-origin'";
|
||||||
more_set_headers "Content-Security-Policy : upgrade-insecure-requests; object-src 'none'; script-src https: 'unsafe-eval'";
|
more_set_headers "Content-Security-Policy : upgrade-insecure-requests; object-src 'none'; script-src https: 'unsafe-eval'";
|
||||||
more_set_headers "X-Content-Type-Options : nosniff";
|
|
||||||
more_set_headers "X-XSS-Protection : 1; mode=block";
|
|
||||||
more_set_headers "X-Download-Options : noopen";
|
|
||||||
more_set_headers "X-Permitted-Cross-Domain-Policies : none";
|
|
||||||
more_set_headers "X-Frame-Options : SAMEORIGIN";
|
|
||||||
|
|
||||||
# Disable gzip to protect against BREACH
|
|
||||||
# Read https://trac.nginx.org/nginx/ticket/1720 (text/html cannot be disabled!)
|
|
||||||
gzip off;
|
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
return 302 https://$http_host/yunohost/admin;
|
return 302 https://$http_host/yunohost/admin;
|
||||||
|
|
|
@ -18,35 +18,45 @@ append_dot_mydomain = no
|
||||||
readme_directory = no
|
readme_directory = no
|
||||||
|
|
||||||
# -- TLS for incoming connections
|
# -- TLS for incoming connections
|
||||||
# By default, TLS is disabled in the Postfix SMTP server, so no difference to
|
###############################################################################
|
||||||
# plain Postfix is visible. Explicitly switch it on with "smtpd_tls_security_level = may".
|
# generated 2020-04-03, Mozilla Guideline v5.4, Postfix 3.1.14, OpenSSL 1.1.0l, intermediate configuration
|
||||||
smtpd_tls_security_level=may
|
# https://ssl-config.mozilla.org/#server=postfix&version=3.1.14&config=intermediate&openssl=1.1.0l&guideline=5.4
|
||||||
|
|
||||||
# Sending AUTH data over an unencrypted channel poses a security risk.
|
# (No modern conf support until we're on buster...)
|
||||||
# When TLS layer encryption is optional ("smtpd_tls_security_level = may"), it
|
# {% if compatibility == "intermediate" %} {% else %} {% endif %}
|
||||||
# may however still be useful to only offer AUTH when TLS is active. To maintain
|
|
||||||
# compatibility with non-TLS clients, the default is to accept AUTH without
|
smtpd_use_tls = yes
|
||||||
# encryption. In order to change this behavior, we set "smtpd_tls_auth_only = yes".
|
|
||||||
smtpd_tls_auth_only=yes
|
smtpd_tls_security_level = may
|
||||||
|
smtpd_tls_auth_only = yes
|
||||||
smtpd_tls_cert_file = /etc/yunohost/certs/{{ main_domain }}/crt.pem
|
smtpd_tls_cert_file = /etc/yunohost/certs/{{ main_domain }}/crt.pem
|
||||||
smtpd_tls_key_file = /etc/yunohost/certs/{{ main_domain }}/key.pem
|
smtpd_tls_key_file = /etc/yunohost/certs/{{ main_domain }}/key.pem
|
||||||
smtpd_tls_exclude_ciphers = aNULL, MD5, DES, ADH, RC4, 3DES
|
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
|
||||||
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
|
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
|
||||||
smtpd_tls_loglevel=1
|
# smtpd_tls_mandatory_ciphers = medium # (c.f. below)
|
||||||
{% if compatibility == "intermediate" %}
|
|
||||||
smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3
|
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam.pem
|
||||||
{% else %}
|
# not actually 1024 bits, this applies to all DHE >= 1024 bits
|
||||||
smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1
|
# smtpd_tls_dh1024_param_file = /path/to/dhparam.pem
|
||||||
{% endif %}
|
|
||||||
|
# This custom medium cipherlist recommendation only works if we have a DH ... which we don't, c.f. https://github.com/YunoHost/issues/issues/93
|
||||||
|
# On the other hand, the postfix doc strongly discourage tweaking this list ... So whatever, let's keep the mandatory_ciphers to high like we did before applying the Mozilla recommendation ...
|
||||||
|
#tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
||||||
|
tls_preempt_cipherlist = no
|
||||||
|
|
||||||
|
# Custom Yunohost stuff ... because we can't use the recommendation about medium cipher list ...
|
||||||
smtpd_tls_mandatory_ciphers=high
|
smtpd_tls_mandatory_ciphers=high
|
||||||
smtpd_tls_eecdh_grade = ultra
|
smtpd_tls_eecdh_grade = ultra
|
||||||
|
###############################################################################
|
||||||
|
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
|
||||||
|
smtpd_tls_loglevel=1
|
||||||
|
|
||||||
# -- TLS for outgoing connections
|
# -- TLS for outgoing connections
|
||||||
# Use TLS if this is supported by the remote SMTP server, otherwise use plaintext.
|
# Use TLS if this is supported by the remote SMTP server, otherwise use plaintext.
|
||||||
smtp_tls_security_level=may
|
smtp_tls_security_level=may
|
||||||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||||
smtp_tls_exclude_ciphers = $smtpd_tls_exclude_ciphers
|
smtp_tls_exclude_ciphers = aNULL, MD5, DES, ADH, RC4, 3DES
|
||||||
smtp_tls_mandatory_ciphers= $smtpd_tls_mandatory_ciphers
|
smtp_tls_mandatory_ciphers= high
|
||||||
smtp_tls_loglevel=1
|
smtp_tls_loglevel=1
|
||||||
|
|
||||||
# Configure Root CA certificates
|
# Configure Root CA certificates
|
||||||
|
@ -167,4 +177,4 @@ default_destination_rate_delay = 5s
|
||||||
# By default it's possible to detect if the email adress exist
|
# By default it's possible to detect if the email adress exist
|
||||||
# So it's easly possible to scan a server to know which email adress is valid
|
# So it's easly possible to scan a server to know which email adress is valid
|
||||||
# and after to send spam
|
# and after to send spam
|
||||||
disable_vrfy_command = yes
|
disable_vrfy_command = yes
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
server_host = localhost
|
server_host = localhost
|
||||||
server_port = 389
|
server_port = 389
|
||||||
search_base = dc=yunohost,dc=org
|
search_base = dc=yunohost,dc=org
|
||||||
query_filter = (&(objectClass=mailAccount)(mail=%s)(permission=cn=main.mail,ou=permission,dc=yunohost,dc=org))
|
query_filter = (&(objectClass=mailAccount)(mail=%s)(permission=cn=mail.main,ou=permission,dc=yunohost,dc=org))
|
||||||
result_attribute = uid
|
result_attribute = uid
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
server_host = localhost
|
server_host = localhost
|
||||||
server_port = 389
|
server_port = 389
|
||||||
search_base = dc=yunohost,dc=org
|
search_base = dc=yunohost,dc=org
|
||||||
query_filter = (&(objectClass=mailAccount)(mail=%s)(permission=cn=main.mail,ou=permission,dc=yunohost,dc=org))
|
query_filter = (&(objectClass=mailAccount)(mail=%s)(permission=cn=mail.main,ou=permission,dc=yunohost,dc=org))
|
||||||
result_attribute = maildrop
|
result_attribute = maildrop
|
||||||
|
|
|
@ -75,6 +75,7 @@ index cn,mail eq
|
||||||
index gidNumber,uidNumber eq
|
index gidNumber,uidNumber eq
|
||||||
index member,memberUid,uniqueMember eq
|
index member,memberUid,uniqueMember eq
|
||||||
index virtualdomain eq
|
index virtualdomain eq
|
||||||
|
index permission eq
|
||||||
|
|
||||||
# Save the time that the entry gets modified, for database #1
|
# Save the time that the entry gets modified, for database #1
|
||||||
lastmod on
|
lastmod on
|
||||||
|
|
9
data/templates/slapd/systemd-override.conf
Normal file
9
data/templates/slapd/systemd-override.conf
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Service]
|
||||||
|
# Prevent slapd from getting killed by oom reaper as much as possible
|
||||||
|
OOMScoreAdjust=-1000
|
||||||
|
# If slapd exited (for instance if got killed) the service should not be
|
||||||
|
# considered as active anymore...
|
||||||
|
RemainAfterExit=no
|
||||||
|
# Automatically restart the service if the service gets down
|
||||||
|
Restart=always
|
||||||
|
RestartSec=3
|
|
@ -192,7 +192,7 @@ authorityKeyIdentifier=keyid,issuer
|
||||||
basicConstraints = CA:FALSE
|
basicConstraints = CA:FALSE
|
||||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||||
|
|
||||||
subjectAltName=DNS:yunohost.org,DNS:www.yunohost.org,DNS:ns.yunohost.org
|
subjectAltName=DNS:yunohost.org,DNS:www.yunohost.org,DNS:ns.yunohost.org,DNS:xmpp-upload.yunohost.org
|
||||||
|
|
||||||
[ v3_ca ]
|
[ v3_ca ]
|
||||||
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
# The VCS to use.
|
|
||||||
#VCS="hg"
|
|
||||||
VCS="git"
|
|
||||||
#VCS="bzr"
|
|
||||||
#VCS="darcs"
|
|
||||||
|
|
||||||
# Options passed to git commit when run by etckeeper.
|
|
||||||
GIT_COMMIT_OPTIONS="--quiet"
|
|
||||||
|
|
||||||
# Options passed to hg commit when run by etckeeper.
|
|
||||||
HG_COMMIT_OPTIONS=""
|
|
||||||
|
|
||||||
# Options passed to bzr commit when run by etckeeper.
|
|
||||||
BZR_COMMIT_OPTIONS=""
|
|
||||||
|
|
||||||
# Options passed to darcs record when run by etckeeper.
|
|
||||||
DARCS_COMMIT_OPTIONS="-a"
|
|
||||||
|
|
||||||
# Uncomment to avoid etckeeper committing existing changes
|
|
||||||
# to /etc automatically once per day.
|
|
||||||
#AVOID_DAILY_AUTOCOMMITS=1
|
|
||||||
|
|
||||||
# Uncomment the following to avoid special file warning
|
|
||||||
# (the option is enabled automatically by cronjob regardless).
|
|
||||||
#AVOID_SPECIAL_FILE_WARNING=1
|
|
||||||
|
|
||||||
# Uncomment to avoid etckeeper committing existing changes to
|
|
||||||
# /etc before installation. It will cancel the installation,
|
|
||||||
# so you can commit the changes by hand.
|
|
||||||
#AVOID_COMMIT_BEFORE_INSTALL=1
|
|
||||||
|
|
||||||
# The high-level package manager that's being used.
|
|
||||||
# (apt, pacman-g2, yum, zypper etc)
|
|
||||||
HIGHLEVEL_PACKAGE_MANAGER=apt
|
|
||||||
|
|
||||||
# The low-level package manager that's being used.
|
|
||||||
# (dpkg, rpm, pacman, pacman-g2, etc)
|
|
||||||
LOWLEVEL_PACKAGE_MANAGER=dpkg
|
|
||||||
|
|
||||||
# To push each commit to a remote, put the name of the remote here.
|
|
||||||
# (eg, "origin" for git). Space-separated lists of multiple remotes
|
|
||||||
# also work (eg, "origin gitlab github" for git).
|
|
||||||
PUSH_REMOTE=""
|
|
|
@ -1,37 +1,56 @@
|
||||||
nginx:
|
avahi-daemon: {}
|
||||||
log: /var/log/nginx
|
dnsmasq: {}
|
||||||
avahi-daemon:
|
|
||||||
log: /var/log/daemon.log
|
|
||||||
dnsmasq:
|
|
||||||
log: /var/log/daemon.log
|
|
||||||
fail2ban:
|
|
||||||
log: /var/log/fail2ban.log
|
|
||||||
dovecot:
|
dovecot:
|
||||||
log: [/var/log/mail.log,/var/log/mail.err]
|
log: [/var/log/mail.log,/var/log/mail.err]
|
||||||
postfix:
|
needs_exposed_ports: [993]
|
||||||
log: [/var/log/mail.log,/var/log/mail.err]
|
category: email
|
||||||
rspamd:
|
fail2ban:
|
||||||
log: /var/log/rspamd/rspamd.log
|
log: /var/log/fail2ban.log
|
||||||
redis-server:
|
category: security
|
||||||
log: /var/log/redis/redis-server.log
|
|
||||||
mysql:
|
|
||||||
log: [/var/log/mysql.log,/var/log/mysql.err]
|
|
||||||
alternates: ['mariadb']
|
|
||||||
glances: {}
|
|
||||||
ssh:
|
|
||||||
log: /var/log/auth.log
|
|
||||||
metronome:
|
metronome:
|
||||||
log: [/var/log/metronome/metronome.log,/var/log/metronome/metronome.err]
|
log: [/var/log/metronome/metronome.log,/var/log/metronome/metronome.err]
|
||||||
slapd:
|
needs_exposed_ports: [5222, 5269]
|
||||||
log: /var/log/syslog
|
category: xmpp
|
||||||
|
mysql:
|
||||||
|
log: [/var/log/mysql.log,/var/log/mysql.err,/var/log/mysql/error.log]
|
||||||
|
actual_systemd_service: mariadb
|
||||||
|
category: database
|
||||||
|
nginx:
|
||||||
|
log: /var/log/nginx
|
||||||
|
test_conf: nginx -t
|
||||||
|
needs_exposed_ports: [80, 443]
|
||||||
|
category: web
|
||||||
|
nslcd: {}
|
||||||
php7.0-fpm:
|
php7.0-fpm:
|
||||||
log: /var/log/php7.0-fpm.log
|
log: /var/log/php7.0-fpm.log
|
||||||
|
test_conf: php-fpm7.0 --test
|
||||||
|
category: web
|
||||||
|
postfix:
|
||||||
|
log: [/var/log/mail.log,/var/log/mail.err]
|
||||||
|
actual_systemd_service: postfix@-
|
||||||
|
needs_exposed_ports: [25, 587]
|
||||||
|
category: email
|
||||||
|
redis-server:
|
||||||
|
log: /var/log/redis/redis-server.log
|
||||||
|
category: database
|
||||||
|
rspamd:
|
||||||
|
log: /var/log/rspamd/rspamd.log
|
||||||
|
category: email
|
||||||
|
slapd:
|
||||||
|
category: database
|
||||||
|
ssh:
|
||||||
|
log: /var/log/auth.log
|
||||||
|
test_conf: sshd -t
|
||||||
|
needs_exposed_ports: [22]
|
||||||
|
category: admin
|
||||||
yunohost-api:
|
yunohost-api:
|
||||||
log: /var/log/yunohost/yunohost-api.log
|
log: /var/log/yunohost/yunohost-api.log
|
||||||
|
category: admin
|
||||||
yunohost-firewall:
|
yunohost-firewall:
|
||||||
need_lock: true
|
need_lock: true
|
||||||
nslcd:
|
test_status: iptables -S | grep "^-A INPUT" | grep " --dport" | grep -q ACCEPT
|
||||||
log: /var/log/syslog
|
category: security
|
||||||
|
glances: null
|
||||||
nsswitch: null
|
nsswitch: null
|
||||||
ssl: null
|
ssl: null
|
||||||
yunohost: null
|
yunohost: null
|
||||||
|
|
302
debian/changelog
vendored
302
debian/changelog
vendored
|
@ -1,3 +1,281 @@
|
||||||
|
yunohost (3.8.1.1) testing; urgency=low
|
||||||
|
|
||||||
|
- [fix] Stupid issue about path in debian/install ...
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sun, 19 Apr 2020 07:04:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.8.1) testing; urgency=low
|
||||||
|
|
||||||
|
## Helpers (PHP, apt)
|
||||||
|
|
||||||
|
- New helpers for extra apt repo, PHP version install, and PHP fpm (#881, #928, #929)
|
||||||
|
- Pave the way to migration to php7.3 and future ones (#880, #926)
|
||||||
|
- Option in PHP helper to use a dedicated php service (#915)
|
||||||
|
|
||||||
|
## Diagnosis
|
||||||
|
|
||||||
|
- Many improvements in diagnosis mechanism (#923, #921, #940)
|
||||||
|
|
||||||
|
## Misc fixes, improvements
|
||||||
|
- custom_portal and custom_overlay redirect (#925)
|
||||||
|
- Improve systemd settings for slapd (#933)
|
||||||
|
- Spelling and typo corrections (#931)
|
||||||
|
- Improve translations for French, German, Catalan
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Kay0u, Maniack Crudelis, ljf, E.Gaspar,
|
||||||
|
xaloc33)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sun, 19 Apr 2020 06:20:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.8.0) testing; urgency=low
|
||||||
|
|
||||||
|
# Major stuff
|
||||||
|
|
||||||
|
- [enh] New diagnosis system (#534, #872, #919, a416044, a354425, 4ab3653, decb372, e686dc6, b5d18d6, 69bc124, 937d339, cc2288c, aaa9805, 526a3a2)
|
||||||
|
- [enh] App categories (#778, #853)
|
||||||
|
- [enh] Support XMPP http upload (#831)
|
||||||
|
- [enh] Many small improvements in the way we manage services (#838, fa5c0e9, dd92a34, c97a839)
|
||||||
|
- [enh] Add subcategories management in bash completion (#839)
|
||||||
|
- [mod] Add conflict with apache2 and bind9, other minor changes in Depends (#909, 3bd6a7a, 0a482fd)
|
||||||
|
- [enh] Setting to enable POP3 in email stack (#791)
|
||||||
|
- [enh] Better UX for CLI/API to change maindomain (#796)
|
||||||
|
|
||||||
|
# Misc technical
|
||||||
|
|
||||||
|
- Update ciphers for nginx, postfix and dovecot according to new Mozilla recommendation (#913, #914)
|
||||||
|
- Get rid of domain-specific acme-challenge snippet, use a single snippet included in every conf (#917)
|
||||||
|
- [enh] Persist cookies between multiple ynh_local_curl calls for the same app (#884, #903)
|
||||||
|
- [fix] ynh_find_port didn't detect port already used on UDP (#827, #907)
|
||||||
|
- [fix] prevent firefox to mix CA and server certificate (#857)
|
||||||
|
- [enh] add operation logger for config panel (#869)
|
||||||
|
- [fix] psql helpers: Revoke sessions before dropping tables (#895)
|
||||||
|
- [fix] moulinette logs were never displayed #lol (#758)
|
||||||
|
|
||||||
|
# Tests, cleaning, refactoring
|
||||||
|
|
||||||
|
- Add core CI, improve/fix tests (#856, #863, 6eb8efb, c4590ab, 711cc35, 6c24755)
|
||||||
|
- Refactoring (#805, 101d3be, #784)
|
||||||
|
- Drop some very-old deprecated app helpers (though still somewhat supporting them through hacky patching) (#780)
|
||||||
|
- Drop glances and the old monitoring system (#821)
|
||||||
|
- Drop app_debug (#824)
|
||||||
|
- Drop app's status.json (#834)
|
||||||
|
- Drop ynh_add_skipped/(un)protected_uris helpers (#910)
|
||||||
|
- Use a common security.conf.inc instead of having cipher setting in each nginx's domain file (1285776, 4d99cbe, be8427d, 22b9565)
|
||||||
|
- Don't add weird tmp redirected_urls after postinstall (#902)
|
||||||
|
- Don't do weird stuff with yunohost-firewall during debian's postinst (978d9d5)
|
||||||
|
|
||||||
|
# i18n, messaging
|
||||||
|
|
||||||
|
- Unit tests / lint / cleaning for translation files (#901)
|
||||||
|
- Improve message wording, spelling (8b0c9e5, 9fe43b1, f69ab4c, 0decb64, 986f38f, 8d40c73, 8fe343a, 1d84f17)
|
||||||
|
- Improve translations for French, Catalan, Bengali (Bangladesh), Italian, Dutch, Norwegian Bokmål, Chinese, Occitan, Spanish, Esperanto, German, Nepali, Portuguese, Arabic, Russian, Hungarian, Hindi, Polish, Greek
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Aeris One, Aleks, Allan N., Alvaro, Armando F., Arthur L., Augustin T., Bram, ButterflyOfFire, Damien P., Gustavo M., Jeroen F., Jimmy M., Josué, Kay0u, Maniack Crudelis, Mario, Matthew D., Mélanie C., Patrick B., Quentí, Yasss Gurl, amirale qt, Elie G., ljf, pitchum, Romain R., tituspijean, xaloc33, yalh76)
|
||||||
|
|
||||||
|
-- Kay0u <pierre@kayou.io> Thu, 09 Apr 2020 19:59:18 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.1.2) stable; urgency=low
|
||||||
|
|
||||||
|
- [fix] Be more robust against some situation where some archives are corrupted
|
||||||
|
- [fix] Make nginx regen-conf more robust against broken config or service failing to start, show info to help debugging
|
||||||
|
- [fix] Force-flush the regen-conf for nginx domain conf when adding/removing a domain...
|
||||||
|
- [fix] app_map : Make sure to return / and not empty string for stuff on domain root
|
||||||
|
- [fix] Improve ynh_systemd_action to wait for fail2ban to reload
|
||||||
|
- [fix] Improper use of logger.exception in app.py leading to infamous weird "KeyError: label"
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 27 Apr 2020 23:50:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.1.1) stable; urgency=low
|
||||||
|
|
||||||
|
- [fix] lxc uid number is limited to 65536 by default (0c9a4509)
|
||||||
|
- [fix] also invalidate group cache when creating users (aaabf8c7)
|
||||||
|
- [fix] Make sure to have a path that include sbin for stupid cron jobs (f03bb82a)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sun, 12 Apr 2020 23:15:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.1) stable; urgency=low
|
||||||
|
|
||||||
|
- [enh] Add ynh_permission_has_user helper (#905)
|
||||||
|
- [mod] Change behavior of ynh_setting_delete to try to make migrating away from legacy permissions easier (#906)
|
||||||
|
- [fix] app_config_apply should also return 'app' info (#918)
|
||||||
|
- [fix] uid/gid conflicts in user_create because of inconsistent comparison (#924)
|
||||||
|
- [fix] Ensure metronome owns its directories (1f623830, 031f8a6e)
|
||||||
|
- [mod] Remove useless sudos in helpers (be88a283)
|
||||||
|
- [enh] Improve message wording for services (3c844292)
|
||||||
|
- [enh] Attempt to anonymize data pasted to paste.yunohost.org (f56f4724)
|
||||||
|
- [enh] Lazy load yunohost.certificate to possibly improve perfs (af8981e4)
|
||||||
|
- [fix] Improve logging / debugging (1eef9b67, 7d323814, d17fcaf9, 210d5f3f)
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Bram, Kay0u, Maniack, Matthew D.)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 9 Apr 2020 14:52:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.12) stable; urgency=low
|
||||||
|
|
||||||
|
- Fix previous buggy hotfix about deleting existing primary groups ...
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sat, 28 Mar 2020 14:52:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.11) stable; urgency=low
|
||||||
|
|
||||||
|
- [fix] Mess due to automatic translation tools ~_~
|
||||||
|
|
||||||
|
-- Kay0u <pierre@kayou.io> Fri, 27 Mar 2020 23:49:45 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.10) stable; urgency=low
|
||||||
|
|
||||||
|
- [fix] On some weird setup, this folder and content ain't readable by group ... gotta make sure to make rx for group other slapd will explode
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 27 Mar 2020 21:45:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.9) stable; urgency=low
|
||||||
|
|
||||||
|
- [fix] Automatically remove existing system group if it exists when creating primary groups
|
||||||
|
- [fix] Require moulinette and ssowat to be at least 3.7 to avoid funky situations where regen-conf fails because moulinette ain't upgraded yet
|
||||||
|
- [i18n] Improve translations for Arabic, Bengali, Catalan, Chinese, Dutch, Esperanto, French, German, Greek, Hindi, Hungarian, Italian, Norwegian Bokmål, Occitan, Polish, Portuguese, Russian, Spanish
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Aeris One, Allan N., Alvaro, amirale qt, Armando F., ButterflyOfFire, Elie G., Gustavo M., Jeroen F., Kayou, Mario, Mélanie C., Patrick B., Quentí, tituspijean, xaloc33, yalh76, Yasss Gurl)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 27 Mar 2020 21:00:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.8) stable; urgency=low
|
||||||
|
|
||||||
|
- [fix] App_setting delete add if the key doesn't exist
|
||||||
|
|
||||||
|
-- Kay0u <pierre@kayou.io> Fri, 27 Mar 2020 00:36:46 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.7) stable; urgency=low
|
||||||
|
|
||||||
|
- [fix] Allow public apps with no sso tile (#894)
|
||||||
|
- [fix] Slapd now index permission to avoid log error
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Aleks, Kay0u)
|
||||||
|
|
||||||
|
-- Kay0u <pierre@kayou.io> Thu, 26 Mar 2020 21:53:22 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.6) testing; urgency=low
|
||||||
|
|
||||||
|
- [fix] Make sure the group permission update contains unique elements
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Aleks)
|
||||||
|
|
||||||
|
-- Kay0u <pierre@kayou.io> Sun, 15 Mar 2020 22:34:27 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.5) testing; urgency=low
|
||||||
|
|
||||||
|
- [fix] Permission url (#871)
|
||||||
|
- [fix] DNS resolver (#859)
|
||||||
|
- [fix] Legacy permission management (#868, #855)
|
||||||
|
- [enh] More informations in hooks permission (#877)
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Bram, ljf, Aleks, Josué, Maniack, Kay0u)
|
||||||
|
|
||||||
|
-- Kay0u <pierre@kayou.io> Sun, 15 Mar 2020 15:07:24 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.4) testing; urgency=low
|
||||||
|
|
||||||
|
- [fix] Also add all_users when allowing visitors (#855)
|
||||||
|
- [fix] Fix handling of skipped_uris (c.f. also SSOwat#149)
|
||||||
|
- [i18n] Improve translations for Catalan
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 2 Dec 2019 20:44:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.3) testing; urgency=low
|
||||||
|
|
||||||
|
- [mod] Some refactoring for permissions create/update/reset (#837)
|
||||||
|
- [fix] Fix some edge cases for ynh_secure_remove and ynh_clean_check_starting
|
||||||
|
- [i18n] Improve translations for French, Catalan
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sat, 23 Nov 2019 19:30:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.2) testing; urgency=low
|
||||||
|
|
||||||
|
- [fix] Make sure the users actually exists when migrating legacy custom permissions
|
||||||
|
- [mod] Move debug log dump from ynh_exit_properly to the core after failed app operation (#833)
|
||||||
|
- [enh] Improve app_upgrade error management (#832)
|
||||||
|
- [mod] Refactor group permission (#837)
|
||||||
|
- [enh] Add permission name in permission callback when adding/removing allowed users (#836)
|
||||||
|
- [enh] Improve permission helpers (#840)
|
||||||
|
- [i18n] Improve translations for German, Catalan, Swedish, Spanish, Turkish, Basque, French, Esperanto, Occitan
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 15 Nov 2019 16:45:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0.1) testing; urgency=low
|
||||||
|
|
||||||
|
- Hotfix to avoid having a shitload of warnings displayed during the permission migration
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 31 Oct 2019 20:35:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.7.0) testing; urgency=low
|
||||||
|
|
||||||
|
# ~ Major stuff
|
||||||
|
|
||||||
|
- [enh] Add group and permission mechanism (YunoHost#585, YunoHost#763, YunoHost#789, YunoHost#790, YunoHost#795, YunoHost#797, SSOwat#147, Moulinette#189, YunoHost-admin#257)
|
||||||
|
- [mod] Rework migration system to have independent migrations (YunoHost#768, YunoHost#774, YunoHost-admin#258)
|
||||||
|
- [enh] Many improvements in the way app action failures are handled (YunoHost#769, YunoHost#811)
|
||||||
|
- [enh] Improve checks for system anomalies after app operations (YunoHost#785)
|
||||||
|
- [mod] Spookier warnings for dangerous app installs (YunoHost#814, Moulinette/808f620)
|
||||||
|
- [enh] Support app manifests in toml (YunoHost#748, Moulinette#204, Moulinette/55515cb)
|
||||||
|
- [mod] Get rid of etckeeper (YunoHost#803)
|
||||||
|
- [enh] Quite a lot of messages improvements, string cleaning, language rework... (YunoHost#793, YunoHost#799, YunoHost#823, SSOwat#143, YunoHost#766, YunoHost#767, YunoHost/fd99ef0, YunoHost/92a6315, YunoHost-admin/10ea04a, Moulinette/599bec3, Moulinette#208, Moulinette#213, Moulinette/b7d415d, Moulinette/a8966b8, Moulinette/fdf9a71, Moulinette/d895ae3, Moulinette/bdf0a1c, YunoHost#817, YunoHost#823, YunoHost/79627d7, YunoHost/9ee3d23, YunoHost-admin#265)
|
||||||
|
- [i18n] Improved translations for Catalan, Occitan, French, Esperanto, Arabic, German, Spanish, Norwegian Bokmål, Portuguese
|
||||||
|
|
||||||
|
# Smaller or pretty technical fix/enh
|
||||||
|
|
||||||
|
- [enh] Add unit/functional tests for apps + improve other tests (YunoHost#779, YunoHost#808)
|
||||||
|
- [enh] Preparations for moulinette Python3 migration (Tox, Pytest and unit tests) (Moulinette#203, Moulinette#206, Moulinette#207, Moulinette#210, Moulinette#211 Moulinette#212, Moulinette/2403ee1, Moulinette/69b0d49, Moulinette/49c749c, Moulinette/2c84ee1, Moulinette/cef72f7, YunoHost/6365a26)
|
||||||
|
- [enh] Support python hooks (YunoHost#747)
|
||||||
|
- [enh] Upgrade n version + compatibility with arm64 (YunoHost#753)
|
||||||
|
- [enh] Add OpenLDAP TLS support (YunoHost#755, YunoHost/0a2d1c7, YunoHost/2dc8095)
|
||||||
|
- [enh] Improve PostgreSQL password security (YunoHost#762)
|
||||||
|
- [enh] Integrate actions/config-panel into operation logs (YunoHost#764)
|
||||||
|
- [mod] Assume that apps without any 'path' setting defined aren't webapps (YunoHost#765)
|
||||||
|
- [fix] Set dpkg vendor to YunoHost (YunoHost#749, YunoHost#772)
|
||||||
|
- [enh] Adding variable 'token' to data to redact from logs (YunoHost#783)
|
||||||
|
- [enh] Add --force and --dry-run options to 'yunohost dyndns update' (YunoHost#786)
|
||||||
|
- [fix] Don't throw a fatal error if we can't change the hostname (YunoHost/fe3ecd7)
|
||||||
|
- [enh] Dynamically evaluate proper mariadb-server-<version> (YunoHost/f0440fb)
|
||||||
|
- [fix] Bad format for backup info.json ... (YunoHost/7d0119a)
|
||||||
|
- [fix] Inline buttons responsiveness on migration screen (YunoHost-admin#259)
|
||||||
|
- [enh] Add debug logs to SSOwat (SSOwat#145)
|
||||||
|
- [enh] Add a write_to_yaml utility similar to write_to_json (Moulinette/2e2e627)
|
||||||
|
- [enh] Warn the user about long locks (Moulinette#205)
|
||||||
|
- [mod] Tweak stuff about setuptools and moulinette deps? (Moulinette/b739f27, Moulinette/da00fc9, Moulinette/d8cbbb0)
|
||||||
|
- [fix] Misc micro bugfixes or improvements (YunoHost#743, YunoHost#792, YunoHost/6f48d1d, YunoHost/d516cf8, YunoHost#819, Moulinette/83d9e77, YunoHost/63d364e, YunoHost/68e9724, YunoHost/0849adb, YunoHost/19dbe87, YunoHost/61931f2, YunoHost/6dc720f, YunoHost/4def4df, SSOwat#140, SSOwat#141, YunoHost#829)
|
||||||
|
- [doc] Fix doc building + add doc build tests with Tox (Moulinette/f1ac5b8, Moulinette/df7d478, Moulinette/74c8f79, Moulinette/bcf92c7, Moulinette/af2c80c, Moulinette/d52a574, Moulinette/307f660, Moulinette/dced104, Moulinette/ed3823b)
|
||||||
|
- [enh] READMEs improvements (YunoHost/b3398e7, SSOwat/ee67b6f, Moulinette/1541b74, Moulinette/ad1eeef, YunoHost/25afdd4, YunoHost/73741f6)
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (accross all repo: Yunohost, Moulinette, SSOwat, Yunohost-admin) : advocatux, Aksel K., Aleks, Allan N., amirale qt, Armin P., Bram, ButterflyOfFire, Carles S. A., chema o. r., decentral1se, Emmanuel V., Etienne M., Filip B., Geoff M., htsr, Jibec, Josué, Julien J., Kayou, liberodark, ljf, lucaskev, Lukas D., madtibo, Martin D., Mélanie C., nr 458 h, pitfd, ppr, Quentí, sidddy, troll, tufek yamero, xaloc33, yalh76
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 31 Oct 2019 18:00:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.6.5.3) stable; urgency=low
|
||||||
|
|
||||||
|
- [fix] More general grep for the php/sury dependency nightmare fix (followup of #809)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 29 Oct 2019 03:48:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.6.5.2) stable; urgency=low
|
||||||
|
|
||||||
|
- [fix] Alex was drunk and released an epic stupid bug in stable (2623d385)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 10 Oct 2019 01:00:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.6.5.1) stable; urgency=low
|
||||||
|
|
||||||
|
- [mod] Change maxretry of fail2ban from 6 to 10 (fe8fd1b)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 08 Oct 2019 20:00:00 +0000
|
||||||
|
|
||||||
|
yunohost (3.6.5) stable; urgency=low
|
||||||
|
|
||||||
|
- [enh] Detect and warn early about unavailable full domains... (#798)
|
||||||
|
- [mod] Change maxretry of fail2ban from 6 to 10 (#802)
|
||||||
|
- [fix] Epicly ugly workaround for the goddamn dependency nighmare about sury fucking up php7.0 dependencies (#809)
|
||||||
|
- [fix] Support logfiles not ending with .log in logrotate ... (#810)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 08 Oct 2019 19:00:00 +0000
|
||||||
|
|
||||||
yunohost (3.6.4.6) stable; urgency=low
|
yunohost (3.6.4.6) stable; urgency=low
|
||||||
|
|
||||||
- [fix] Hopefully fix the issue about corrupted logs metadata files (d507d447, 1cec9d78)
|
- [fix] Hopefully fix the issue about corrupted logs metadata files (d507d447, 1cec9d78)
|
||||||
|
@ -91,7 +369,7 @@ yunohost (3.6.1.2) testing; urgency=low
|
||||||
yunohost (3.6.1.1) testing; urgency=low
|
yunohost (3.6.1.1) testing; urgency=low
|
||||||
|
|
||||||
- [fix] Weird issue in slapd triggered by indexing uidNumber / gidNumber
|
- [fix] Weird issue in slapd triggered by indexing uidNumber / gidNumber
|
||||||
|
|
||||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 04 Jun 2019 15:10:00 +0000
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 04 Jun 2019 15:10:00 +0000
|
||||||
|
|
||||||
yunohost (3.6.1) testing; urgency=low
|
yunohost (3.6.1) testing; urgency=low
|
||||||
|
@ -561,19 +839,19 @@ yunohost (3.0.0~beta1.2) testing; urgency=low
|
||||||
|
|
||||||
Removing http2 also from yunohost_admin.conf since there still are some
|
Removing http2 also from yunohost_admin.conf since there still are some
|
||||||
issues with wordpress ?
|
issues with wordpress ?
|
||||||
|
|
||||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 08 May 2018 05:52:00 +0000
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 08 May 2018 05:52:00 +0000
|
||||||
|
|
||||||
yunohost (3.0.0~beta1.1) testing; urgency=low
|
yunohost (3.0.0~beta1.1) testing; urgency=low
|
||||||
|
|
||||||
Fixes in the postgresql migration
|
Fixes in the postgresql migration
|
||||||
|
|
||||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Sun, 06 May 2018 03:06:00 +0000
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sun, 06 May 2018 03:06:00 +0000
|
||||||
|
|
||||||
yunohost (3.0.0~beta1) testing; urgency=low
|
yunohost (3.0.0~beta1) testing; urgency=low
|
||||||
|
|
||||||
Beta release for Stretch
|
Beta release for Stretch
|
||||||
|
|
||||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 03 May 2018 03:04:45 +0000
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 03 May 2018 03:04:45 +0000
|
||||||
|
|
||||||
yunohost (2.7.14) stable; urgency=low
|
yunohost (2.7.14) stable; urgency=low
|
||||||
|
@ -612,7 +890,7 @@ yunohost (2.7.13.4) testing; urgency=low
|
||||||
* Increase backup filename length
|
* Increase backup filename length
|
||||||
|
|
||||||
(Fixes by Bram <3)
|
(Fixes by Bram <3)
|
||||||
|
|
||||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 05 Jun 2018 18:22:00 +0000
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 05 Jun 2018 18:22:00 +0000
|
||||||
|
|
||||||
yunohost (2.7.13.3) testing; urgency=low
|
yunohost (2.7.13.3) testing; urgency=low
|
||||||
|
@ -703,7 +981,7 @@ yunohost (2.7.11) testing; urgency=low
|
||||||
* [helpers] Allow for 'or' in dependencies (#381)
|
* [helpers] Allow for 'or' in dependencies (#381)
|
||||||
* [helpers] Tweak the usage of BACKUP_CORE_ONLY (#398)
|
* [helpers] Tweak the usage of BACKUP_CORE_ONLY (#398)
|
||||||
* [helpers] Tweak systemd config helpers (optional service name and template name) (#425)
|
* [helpers] Tweak systemd config helpers (optional service name and template name) (#425)
|
||||||
* [i18n] Improve translations for Arabic, French, German, Occitan, Spanish
|
* [i18n] Improve translations for Arabic, French, German, Occitan, Spanish
|
||||||
|
|
||||||
Thanks to all contributors (ariasuni, ljf, JimboJoe, frju365, Maniack, J-B Lescher, Josue, Aleks, Bram, jibec) and the several translators (ButterflyOfFire, Eric G., Cedric, J. Keerl, beyercenter, P. Gatzka, Quenti, bjarkan) <3 !
|
Thanks to all contributors (ariasuni, ljf, JimboJoe, frju365, Maniack, J-B Lescher, Josue, Aleks, Bram, jibec) and the several translators (ButterflyOfFire, Eric G., Cedric, J. Keerl, beyercenter, P. Gatzka, Quenti, bjarkan) <3 !
|
||||||
|
|
||||||
|
@ -794,11 +1072,11 @@ yunohost (2.7.3) testing; urgency=low
|
||||||
Major changes :
|
Major changes :
|
||||||
|
|
||||||
* [fix] Refactor/clean madness related to DynDNS (#353)
|
* [fix] Refactor/clean madness related to DynDNS (#353)
|
||||||
* [i18n] Improve french translation (#355)
|
* [i18n] Improve french translation (#355)
|
||||||
* [fix] Use cryptorandom to generate password (#358)
|
* [fix] Use cryptorandom to generate password (#358)
|
||||||
* [enh] Support for single app upgrade from the webadmin (#359)
|
* [enh] Support for single app upgrade from the webadmin (#359)
|
||||||
* [enh] Be able to give lock to son processes detached by systemctl (#367)
|
* [enh] Be able to give lock to son processes detached by systemctl (#367)
|
||||||
* [enh] Make MySQL dumps with a single transaction to ensure backup consistency (#370)
|
* [enh] Make MySQL dumps with a single transaction to ensure backup consistency (#370)
|
||||||
|
|
||||||
Misc fixes/improvements :
|
Misc fixes/improvements :
|
||||||
|
|
||||||
|
@ -806,7 +1084,7 @@ yunohost (2.7.3) testing; urgency=low
|
||||||
* [fix] Allow dash at the beginning of app settings value (#357)
|
* [fix] Allow dash at the beginning of app settings value (#357)
|
||||||
* [enh] Handle root path in nginx conf (#361)
|
* [enh] Handle root path in nginx conf (#361)
|
||||||
* [enh] Add debugging in ldap init (#365)
|
* [enh] Add debugging in ldap init (#365)
|
||||||
* [fix] Fix app_upgrade_string with missing key
|
* [fix] Fix app_upgrade_string with missing key
|
||||||
* [fix] Fix for change_url path normalizing with root url (#368)
|
* [fix] Fix for change_url path normalizing with root url (#368)
|
||||||
* [fix] Missing 'ask_path' string (#369)
|
* [fix] Missing 'ask_path' string (#369)
|
||||||
* [enh] Remove date from sql dump (#371)
|
* [enh] Remove date from sql dump (#371)
|
||||||
|
@ -853,7 +1131,7 @@ yunohost (2.7.1) testing; urgency=low
|
||||||
* [fix] Make read-only mount bind actually read-only (#343) (ljf)
|
* [fix] Make read-only mount bind actually read-only (#343) (ljf)
|
||||||
### dyndns
|
### dyndns
|
||||||
* Regen dnsmasq conf if it's not up to date :| (Alexandre Aubin)
|
* Regen dnsmasq conf if it's not up to date :| (Alexandre Aubin)
|
||||||
* [fix] timeout on request to avoid blocking process (Laurent Peuch)
|
* [fix] timeout on request to avoid blocking process (Laurent Peuch)
|
||||||
* Put request url in an intermediate variable (Alexandre Aubin)
|
* Put request url in an intermediate variable (Alexandre Aubin)
|
||||||
### other
|
### other
|
||||||
* clean users.py (Laurent Peuch)
|
* clean users.py (Laurent Peuch)
|
||||||
|
@ -1587,7 +1865,7 @@ yunohost (2.3.12) testing; urgency=low
|
||||||
* [fix] Check for tty in root_handlers before remove it in bin/yunohost
|
* [fix] Check for tty in root_handlers before remove it in bin/yunohost
|
||||||
* [fix] Use dyndns.yunohost.org instead of dynhost.yunohost.org
|
* [fix] Use dyndns.yunohost.org instead of dynhost.yunohost.org
|
||||||
* [fix] Set found private key and don't validate it in dyndns_update
|
* [fix] Set found private key and don't validate it in dyndns_update
|
||||||
* [fix] Update first registered domain with DynDNS instead of current_host
|
* [fix] Update first registered domain with DynDNS instead of current_host
|
||||||
* [i18n] Rename app_requirements_failed err named variable
|
* [i18n] Rename app_requirements_failed err named variable
|
||||||
* [i18n] Update translations from Weblate
|
* [i18n] Update translations from Weblate
|
||||||
|
|
||||||
|
@ -1595,7 +1873,7 @@ yunohost (2.3.12) testing; urgency=low
|
||||||
* [enh] Better message during service regenconf.
|
* [enh] Better message during service regenconf.
|
||||||
* [enh] Display hook path on error message.
|
* [enh] Display hook path on error message.
|
||||||
* [enh] Use named arguments when calling m18n in service.py
|
* [enh] Use named arguments when calling m18n in service.py
|
||||||
* [enh] Use named arguments with m18n.
|
* [enh] Use named arguments with m18n.
|
||||||
* [enh] Use named arguments for user_unknown string.
|
* [enh] Use named arguments for user_unknown string.
|
||||||
|
|
||||||
-- Jérôme Lebleu <jerome@yunohost.org> Sat, 09 Apr 2016 12:13:10 +0200
|
-- Jérôme Lebleu <jerome@yunohost.org> Sat, 09 Apr 2016 12:13:10 +0200
|
||||||
|
|
30
debian/control
vendored
30
debian/control
vendored
|
@ -11,27 +11,28 @@ Package: yunohost
|
||||||
Essential: yes
|
Essential: yes
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: ${python:Depends}, ${misc:Depends}
|
Depends: ${python:Depends}, ${misc:Depends}
|
||||||
, moulinette (>= 2.7.1), ssowat (>= 2.7.1)
|
, moulinette (>= 3.7), ssowat (>= 3.7)
|
||||||
, python-psutil, python-requests, python-dnspython, python-openssl
|
, python-psutil, python-requests, python-dnspython, python-openssl
|
||||||
, python-apt, python-miniupnpc, python-dbus, python-jinja2
|
, python-apt, python-miniupnpc, python-dbus, python-jinja2
|
||||||
, python-toml
|
, python-toml
|
||||||
, glances, apt-transport-https
|
, apt, apt-transport-https
|
||||||
, dnsutils, bind9utils, unzip, git, curl, cron, wget, jq
|
, nginx, nginx-extras (>=1.6.2)
|
||||||
, ca-certificates, netcat-openbsd, iproute
|
, php-fpm, php-ldap, php-intl
|
||||||
, mariadb-server, php-mysql | php-mysqlnd
|
, mariadb-server, php-mysql | php-mysqlnd
|
||||||
|
, openssh-server, iptables, fail2ban, dnsutils, bind9utils
|
||||||
|
, openssl, ca-certificates, netcat-openbsd, iproute2
|
||||||
, slapd, ldap-utils, sudo-ldap, libnss-ldapd, unscd, libpam-ldapd
|
, slapd, ldap-utils, sudo-ldap, libnss-ldapd, unscd, libpam-ldapd
|
||||||
, postfix-ldap, postfix-policyd-spf-perl, postfix-pcre, procmail, mailutils, postsrsd
|
, dnsmasq, avahi-daemon, libnss-mdns, resolvconf, libnss-myhostname
|
||||||
, dovecot-ldap, dovecot-lmtpd, dovecot-managesieved
|
, postfix, postfix-ldap, postfix-policyd-spf-perl, postfix-pcre
|
||||||
, dovecot-antispam, fail2ban, iptables
|
, dovecot-core, dovecot-ldap, dovecot-lmtpd, dovecot-managesieved, dovecot-antispam
|
||||||
, nginx-extras (>=1.6.2), php-fpm, php-ldap, php-intl
|
, rspamd (>= 1.6.0), opendkim-tools, postsrsd, procmail, mailutils
|
||||||
, dnsmasq, openssl, avahi-daemon, libnss-mdns, resolvconf, libnss-myhostname
|
, redis-server
|
||||||
, metronome
|
, metronome
|
||||||
, rspamd (>= 1.6.0), redis-server, opendkim-tools
|
, git, curl, wget, cron, unzip, jq
|
||||||
, haveged, fake-hwclock
|
, lsb-release, haveged, fake-hwclock, equivs, lsof
|
||||||
, equivs, lsof
|
|
||||||
Recommends: yunohost-admin
|
Recommends: yunohost-admin
|
||||||
, openssh-server, ntp, inetutils-ping | iputils-ping
|
, ntp, inetutils-ping | iputils-ping
|
||||||
, bash-completion, rsyslog, etckeeper
|
, bash-completion, rsyslog
|
||||||
, php-gd, php-curl, php-gettext, php-mcrypt
|
, php-gd, php-curl, php-gettext, php-mcrypt
|
||||||
, python-pip
|
, python-pip
|
||||||
, unattended-upgrades
|
, unattended-upgrades
|
||||||
|
@ -43,6 +44,7 @@ Conflicts: iptables-persistent
|
||||||
, yunohost-config-dovecot, yunohost-config-slapd
|
, yunohost-config-dovecot, yunohost-config-slapd
|
||||||
, yunohost-config-nginx, yunohost-config-amavis
|
, yunohost-config-nginx, yunohost-config-amavis
|
||||||
, yunohost-config-mysql, yunohost-predepends
|
, yunohost-config-mysql, yunohost-predepends
|
||||||
|
, apache2, bind9
|
||||||
Replaces: moulinette-yunohost, yunohost-config
|
Replaces: moulinette-yunohost, yunohost-config
|
||||||
, yunohost-config-others, yunohost-config-postfix
|
, yunohost-config-others, yunohost-config-postfix
|
||||||
, yunohost-config-dovecot, yunohost-config-slapd
|
, yunohost-config-dovecot, yunohost-config-slapd
|
||||||
|
|
2
debian/copyright
vendored
2
debian/copyright
vendored
|
@ -1,5 +1,5 @@
|
||||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
Source: https://github.com/YunoHost/moulinette-yunohost
|
Source: https://github.com/YunoHost/yunohost
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2015 YUNOHOST.ORG
|
Copyright: 2015 YUNOHOST.ORG
|
||||||
|
|
1
debian/install
vendored
1
debian/install
vendored
|
@ -7,6 +7,7 @@ data/hooks/* /usr/share/yunohost/hooks/
|
||||||
data/other/yunoprompt.service /etc/systemd/system/
|
data/other/yunoprompt.service /etc/systemd/system/
|
||||||
data/other/password/* /usr/share/yunohost/other/password/
|
data/other/password/* /usr/share/yunohost/other/password/
|
||||||
data/other/dpkg-origins/yunohost /etc/dpkg/origins
|
data/other/dpkg-origins/yunohost /etc/dpkg/origins
|
||||||
|
data/other/dnsbl_list.yml /usr/share/yunohost/other/
|
||||||
data/other/* /usr/share/yunohost/yunohost-config/moulinette/
|
data/other/* /usr/share/yunohost/yunohost-config/moulinette/
|
||||||
data/templates/* /usr/share/yunohost/templates/
|
data/templates/* /usr/share/yunohost/templates/
|
||||||
data/helpers /usr/share/yunohost/
|
data/helpers /usr/share/yunohost/
|
||||||
|
|
31
debian/postinst
vendored
31
debian/postinst
vendored
|
@ -14,17 +14,14 @@ do_configure() {
|
||||||
echo "Regenerating configuration, this might take a while..."
|
echo "Regenerating configuration, this might take a while..."
|
||||||
yunohost tools regen-conf --output-as none
|
yunohost tools regen-conf --output-as none
|
||||||
|
|
||||||
echo "Launching migrations.."
|
echo "Launching migrations..."
|
||||||
yunohost tools migrations migrate --auto
|
yunohost tools migrations migrate --auto
|
||||||
|
|
||||||
# restart yunohost-firewall if it's running
|
echo "Re-diagnosing server health..."
|
||||||
service yunohost-firewall status >/dev/null \
|
yunohost diagnosis run --force
|
||||||
&& restart_yunohost_firewall \
|
|
||||||
|| echo "yunohost-firewall service is not running, you should " \
|
|
||||||
"consider to start it by doing 'service yunohost-firewall start'."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Change dpkg vendor
|
# Change dpkg vendor
|
||||||
# see https://wiki.debian.org/Derivatives/Guidelines#Vendor
|
# see https://wiki.debian.org/Derivatives/Guidelines#Vendor
|
||||||
readlink -f /etc/dpkg/origins/default | grep -q debian \
|
readlink -f /etc/dpkg/origins/default | grep -q debian \
|
||||||
&& rm -f /etc/dpkg/origins/default \
|
&& rm -f /etc/dpkg/origins/default \
|
||||||
|
@ -39,24 +36,6 @@ do_configure() {
|
||||||
pam-auth-update --package
|
pam-auth-update --package
|
||||||
}
|
}
|
||||||
|
|
||||||
restart_yunohost_firewall() {
|
|
||||||
echo "Restarting YunoHost firewall..."
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
# summary of how this script can be called:
|
# summary of how this script can be called:
|
||||||
# * <postinst> `configure' <most-recently-configured-version>
|
# * <postinst> `configure' <most-recently-configured-version>
|
||||||
# * <old-postinst> `abort-upgrade' <new version>
|
# * <old-postinst> `abort-upgrade' <new version>
|
||||||
|
|
335
locales/ar.json
335
locales/ar.json
|
@ -1,389 +1,110 @@
|
||||||
{
|
{
|
||||||
"action_invalid": "إجراء غير صالح '{action:s}'",
|
"action_invalid": "إجراء غير صالح '{action:s}'",
|
||||||
"admin_password": "كلمة السر الإدارية",
|
"admin_password": "كلمة السر الإدارية",
|
||||||
"admin_password_change_failed": "تعذرت عملية تعديل كلمة السر",
|
"admin_password_change_failed": "لا يمكن تعديل الكلمة السرية",
|
||||||
"admin_password_changed": "تم تعديل الكلمة السرية الإدارية",
|
"admin_password_changed": "تم تعديل الكلمة السرية الإدارية",
|
||||||
"app_already_installed": "{app:s} تم تنصيبه مِن قبل",
|
"app_already_installed": "{app:s} تم تنصيبه مِن قبل",
|
||||||
"app_already_installed_cant_change_url": "",
|
|
||||||
"app_already_up_to_date": "{app:s} تم تحديثه مِن قَبل",
|
"app_already_up_to_date": "{app:s} تم تحديثه مِن قَبل",
|
||||||
"app_argument_choice_invalid": "",
|
|
||||||
"app_argument_invalid": "",
|
|
||||||
"app_argument_required": "المُعامِل '{name:s}' مطلوب",
|
"app_argument_required": "المُعامِل '{name:s}' مطلوب",
|
||||||
"app_change_no_change_url_script": "إنّ التطبيق {app_name:s} لا يدعم تغيير الرابط، مِن الممكن أنه يتوجب عليكم تحدثيه.",
|
"app_change_url_failed_nginx_reload": "فشلت عملية إعادة تشغيل NGINX. ها هي نتيجة الأمر 'nginx -t':\n{nginx_errors:s}",
|
||||||
"app_change_url_failed_nginx_reload": "فشلت عملية إعادة تشغيل nginx. ها هي نتيجة الأمر 'nginx -t':\n{nginx_errors:s}",
|
|
||||||
"app_change_url_identical_domains": "The old and new domain/url_path are identical ('{domain:s}{path:s}'), nothing to do.",
|
|
||||||
"app_change_url_no_script": "This application '{app_name:s}' doesn't support url modification yet. Maybe you should upgrade the application.",
|
|
||||||
"app_change_url_success": "Successfully changed {app:s} url to {domain:s}{path:s}",
|
|
||||||
"app_extraction_failed": "تعذر فك الضغط عن ملفات التنصيب",
|
"app_extraction_failed": "تعذر فك الضغط عن ملفات التنصيب",
|
||||||
"app_id_invalid": "Invalid app id",
|
|
||||||
"app_incompatible": "إن التطبيق {app} غير متوافق مع إصدار واي يونوهوست YunoHost الخاص بك",
|
|
||||||
"app_install_files_invalid": "ملفات التنصيب خاطئة",
|
"app_install_files_invalid": "ملفات التنصيب خاطئة",
|
||||||
"app_location_already_used": "The app '{app}' is already installed on that location ({path})",
|
|
||||||
"app_make_default_location_already_used": "Can't make the app '{app}' the default on the domain {domain} is already used by the other app '{other_app}'",
|
|
||||||
"app_location_install_failed": "Unable to install the app in this location because it conflit with the app '{other_app}' already installed on '{other_path}'",
|
|
||||||
"app_location_unavailable": "This url is not available or conflicts with an already installed app",
|
|
||||||
"app_manifest_invalid": "Invalid app manifest: {error}",
|
|
||||||
"app_no_upgrade": "ليس هناك أي تطبيق بحاجة إلى تحديث",
|
|
||||||
"app_not_correctly_installed": "يبدو أن التطبيق {app:s} لم يتم تنصيبه بشكل صحيح",
|
"app_not_correctly_installed": "يبدو أن التطبيق {app:s} لم يتم تنصيبه بشكل صحيح",
|
||||||
"app_not_installed": "إنّ التطبيق {app:s} غير مُنصَّب",
|
"app_not_installed": "إنّ التطبيق {app:s} غير مُنصَّب",
|
||||||
"app_not_properly_removed": "لم يتم حذف تطبيق {app:s} بشكلٍ جيّد",
|
"app_not_properly_removed": "لم يتم حذف تطبيق {app:s} بشكلٍ جيّد",
|
||||||
"app_package_need_update": "The app {app} package needs to be updated to follow YunoHost changes",
|
|
||||||
"app_removed": "تمت إزالة تطبيق {app:s}",
|
"app_removed": "تمت إزالة تطبيق {app:s}",
|
||||||
"app_requirements_checking": "جار فحص الحزم اللازمة لـ {app}…",
|
"app_requirements_checking": "جار فحص الحزم اللازمة لـ {app}…",
|
||||||
"app_requirements_failed": "Unable to meet requirements for {app}: {error}",
|
|
||||||
"app_requirements_unmeet": "Requirements are not met for {app}, the package {pkgname} ({version}) must be {spec}",
|
|
||||||
"app_sources_fetch_failed": "تعذرت عملية جلب مصادر الملفات",
|
"app_sources_fetch_failed": "تعذرت عملية جلب مصادر الملفات",
|
||||||
"app_unknown": "برنامج مجهول",
|
"app_unknown": "برنامج مجهول",
|
||||||
"app_unsupported_remote_type": "Unsupported remote type used for the app",
|
|
||||||
"app_upgrade_app_name": "جارٍ تحديث تطبيق {app}…",
|
"app_upgrade_app_name": "جارٍ تحديث تطبيق {app}…",
|
||||||
"app_upgrade_failed": "تعذرت عملية ترقية {app:s}",
|
"app_upgrade_failed": "تعذرت عملية ترقية {app:s}",
|
||||||
"app_upgrade_some_app_failed": "تعذرت عملية ترقية بعض التطبيقات",
|
"app_upgrade_some_app_failed": "تعذرت عملية ترقية بعض التطبيقات",
|
||||||
"app_upgraded": "تم تحديث التطبيق {app:s}",
|
"app_upgraded": "تم تحديث التطبيق {app:s}",
|
||||||
"appslist_corrupted_json": "Could not load the application lists. It looks like {filename:s} is corrupted.",
|
|
||||||
"appslist_could_not_migrate": "Could not migrate app list {appslist:s} ! Unable to parse the url... The old cron job has been kept in {bkp_file:s}.",
|
|
||||||
"appslist_fetched": "تم جلب قائمة تطبيقات {appslist:s}",
|
|
||||||
"appslist_migrating": "Migrating application list {appslist:s} …",
|
|
||||||
"appslist_name_already_tracked": "There is already a registered application list with name {name:s}.",
|
|
||||||
"appslist_removed": "تم حذف قائمة التطبيقات {appslist:s}",
|
|
||||||
"appslist_retrieve_bad_format": "Retrieved file for application list {appslist:s} is not valid",
|
|
||||||
"appslist_retrieve_error": "Unable to retrieve the remote application list {appslist:s}: {error:s}",
|
|
||||||
"appslist_unknown": "قائمة التطبيقات {appslist:s} مجهولة.",
|
|
||||||
"appslist_url_already_tracked": "There is already a registered application list with url {url:s}.",
|
|
||||||
"ask_current_admin_password": "كلمة السر الإدارية الحالية",
|
|
||||||
"ask_email": "عنوان البريد الإلكتروني",
|
"ask_email": "عنوان البريد الإلكتروني",
|
||||||
"ask_firstname": "الإسم",
|
"ask_firstname": "الإسم",
|
||||||
"ask_lastname": "اللقب",
|
"ask_lastname": "اللقب",
|
||||||
"ask_list_to_remove": "القائمة المختارة للحذف",
|
|
||||||
"ask_main_domain": "النطاق الرئيسي",
|
"ask_main_domain": "النطاق الرئيسي",
|
||||||
"ask_new_admin_password": "كلمة السر الإدارية الجديدة",
|
"ask_new_admin_password": "كلمة السر الإدارية الجديدة",
|
||||||
"ask_password": "كلمة السر",
|
"ask_password": "كلمة السر",
|
||||||
"ask_path": "المسار",
|
|
||||||
"backup_abstract_method": "This backup method hasn't yet been implemented",
|
|
||||||
"backup_action_required": "You must specify something to save",
|
|
||||||
"backup_app_failed": "Unable to back up the app '{app:s}'",
|
|
||||||
"backup_applying_method_borg": "Sending all files to backup into borg-backup repository…",
|
|
||||||
"backup_applying_method_copy": "جارٍ نسخ كافة الملفات إلى النسخة الإحتياطية …",
|
"backup_applying_method_copy": "جارٍ نسخ كافة الملفات إلى النسخة الإحتياطية …",
|
||||||
"backup_applying_method_custom": "Calling the custom backup method '{method:s}'…",
|
"backup_applying_method_tar": "جارٍ إنشاء ملف TAR للنسخة الاحتياطية…",
|
||||||
"backup_applying_method_tar": "جارٍ إنشاء ملف tar للنسخة الاحتياطية…",
|
|
||||||
"backup_archive_app_not_found": "App '{app:s}' not found in the backup archive",
|
|
||||||
"backup_archive_broken_link": "Unable to access backup archive (broken link to {path:s})",
|
|
||||||
"backup_archive_mount_failed": "Mounting the backup archive failed",
|
|
||||||
"backup_archive_name_exists": "The backup's archive name already exists",
|
|
||||||
"backup_archive_name_unknown": "Unknown local backup archive named '{name:s}'",
|
|
||||||
"backup_archive_open_failed": "Unable to open the backup archive",
|
|
||||||
"backup_archive_system_part_not_available": "System part '{part:s}' not available in this backup",
|
|
||||||
"backup_archive_writing_error": "Unable to add files to backup into the compressed archive",
|
|
||||||
"backup_ask_for_copying_if_needed": "Some files couldn't be prepared to be backuped using the method that avoid to temporarily waste space on the system. To perform the backup, {size:s}MB should be used temporarily. Do you agree?",
|
|
||||||
"backup_borg_not_implemented": "Borg backup method is not yet implemented",
|
|
||||||
"backup_cant_mount_uncompress_archive": "Unable to mount in readonly mode the uncompress archive directory",
|
|
||||||
"backup_cleaning_failed": "Unable to clean-up the temporary backup directory",
|
|
||||||
"backup_copying_to_organize_the_archive": "Copying {size:s}MB to organize the archive",
|
|
||||||
"backup_couldnt_bind": "Couldn't bind {src:s} to {dest:s}.",
|
|
||||||
"backup_created": "تم إنشاء النسخة الإحتياطية",
|
"backup_created": "تم إنشاء النسخة الإحتياطية",
|
||||||
"backup_creating_archive": "جارٍ إنشاء ملف النسخة الاحتياطية…",
|
|
||||||
"backup_creation_failed": "Backup creation failed",
|
|
||||||
"backup_csv_addition_failed": "Unable to add files to backup into the CSV file",
|
|
||||||
"backup_csv_creation_failed": "Unable to create the CSV file needed for future restore operations",
|
|
||||||
"backup_custom_backup_error": "Custom backup method failure on 'backup' step",
|
|
||||||
"backup_custom_mount_error": "Custom backup method failure on 'mount' step",
|
|
||||||
"backup_custom_need_mount_error": "Custom backup method failure on 'need_mount' step",
|
|
||||||
"backup_delete_error": "Unable to delete '{path:s}'",
|
|
||||||
"backup_deleted": "The backup has been deleted",
|
|
||||||
"backup_extracting_archive": "Extracting the backup archive…",
|
|
||||||
"backup_hook_unknown": "Backup hook '{hook:s}' unknown",
|
|
||||||
"backup_invalid_archive": "نسخة إحتياطية غير صالحة",
|
"backup_invalid_archive": "نسخة إحتياطية غير صالحة",
|
||||||
"backup_method_borg_finished": "Backup into borg finished",
|
|
||||||
"backup_method_copy_finished": "إنتهت عملية النسخ الإحتياطي",
|
"backup_method_copy_finished": "إنتهت عملية النسخ الإحتياطي",
|
||||||
"backup_method_custom_finished": "Custom backup method '{method:s}' finished",
|
|
||||||
"backup_method_tar_finished": "Backup tar archive created",
|
|
||||||
"backup_no_uncompress_archive_dir": "Uncompress archive directory doesn't exist",
|
|
||||||
"backup_nothings_done": "ليس هناك أي شيء للحفظ",
|
"backup_nothings_done": "ليس هناك أي شيء للحفظ",
|
||||||
"backup_output_directory_forbidden": "Forbidden output directory. Backups can't be created in /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var or /home/yunohost.backup/archives sub-folders",
|
|
||||||
"backup_output_directory_not_empty": "The output directory is not empty",
|
|
||||||
"backup_output_directory_required": "يتوجب عليك تحديد مجلد لتلقي النسخ الإحتياطية",
|
"backup_output_directory_required": "يتوجب عليك تحديد مجلد لتلقي النسخ الإحتياطية",
|
||||||
"backup_output_symlink_dir_broken": "You have a broken symlink instead of your archives directory '{path:s}'. You may have a specific setup to backup your data on an other filesystem, in this case you probably forgot to remount or plug your hard dirve or usb key.",
|
|
||||||
"backup_running_app_script": "Running backup script of app '{app:s}'...",
|
|
||||||
"backup_running_hooks": "Running backup hooks…",
|
|
||||||
"backup_system_part_failed": "Unable to backup the '{part:s}' system part",
|
|
||||||
"backup_unable_to_organize_files": "Unable to organize files in the archive with the quick method",
|
|
||||||
"backup_with_no_backup_script_for_app": "App {app:s} has no backup script. Ignoring.",
|
|
||||||
"backup_with_no_restore_script_for_app": "App {app:s} has no restore script, you won't be able to automatically restore the backup of this app.",
|
|
||||||
"certmanager_acme_not_configured_for_domain": "Certificate for domain {domain:s} does not appear to be correctly installed. Please run cert-install for this domain first.",
|
|
||||||
"certmanager_attempt_to_renew_nonLE_cert": "The certificate for domain {domain:s} is not issued by Let's Encrypt. Cannot renew it automatically!",
|
|
||||||
"certmanager_attempt_to_renew_valid_cert": "The certificate for domain {domain:s} is not about to expire! Use --force to bypass",
|
|
||||||
"certmanager_attempt_to_replace_valid_cert": "You are attempting to overwrite a good and valid certificate for domain {domain:s}! (Use --force to bypass)",
|
|
||||||
"certmanager_cannot_read_cert": "Something wrong happened when trying to open current certificate for domain {domain:s} (file: {file:s}), reason: {reason:s}",
|
|
||||||
"certmanager_cert_install_success": "تمت عملية تنصيب شهادة Let's Encrypt بنجاح على النطاق {domain:s} !",
|
"certmanager_cert_install_success": "تمت عملية تنصيب شهادة Let's Encrypt بنجاح على النطاق {domain:s} !",
|
||||||
"certmanager_cert_install_success_selfsigned": "نجحت عملية تثبيت الشهادة الموقعة ذاتيا الخاصة بالنطاق {domain:s}!",
|
"certmanager_cert_install_success_selfsigned": "نجحت عملية تثبيت الشهادة الموقعة ذاتيا الخاصة بالنطاق {domain:s}",
|
||||||
"certmanager_cert_renew_success": "نجحت عملية تجديد شهادة Let's Encrypt الخاصة باسم النطاق {domain:s} !",
|
"certmanager_cert_renew_success": "نجحت عملية تجديد شهادة Let's Encrypt الخاصة باسم النطاق {domain:s} !",
|
||||||
"certmanager_cert_signing_failed": "فشل إجراء توقيع الشهادة الجديدة",
|
"certmanager_cert_signing_failed": "فشل إجراء توقيع الشهادة الجديدة",
|
||||||
"certmanager_certificate_fetching_or_enabling_failed": "Sounds like enabling the new certificate for {domain:s} failed somehow…",
|
|
||||||
"certmanager_conflicting_nginx_file": "Unable to prepare domain for ACME challenge: the nginx configuration file {filepath:s} is conflicting and should be removed first",
|
|
||||||
"certmanager_couldnt_fetch_intermediate_cert": "Timed out when trying to fetch intermediate certificate from Let's Encrypt. Certificate installation/renewal aborted - please try again later.",
|
|
||||||
"certmanager_domain_cert_not_selfsigned": "The certificate for domain {domain:s} is not self-signed. Are you sure you want to replace it? (Use --force)",
|
|
||||||
"certmanager_domain_dns_ip_differs_from_public_ip": "The DNS 'A' record for domain {domain:s} is different from this server IP. If you recently modified your A record, please wait for it to propagate (some DNS propagation checkers are available online). (If you know what you are doing, use --no-checks to disable those checks.)",
|
|
||||||
"certmanager_domain_http_not_working": "It seems that the domain {domain:s} cannot be accessed through HTTP. Please check your DNS and nginx configuration is okay",
|
|
||||||
"certmanager_domain_not_resolved_locally": "The domain {domain:s} cannot be resolved from inside your Yunohost server. This might happen if you recently modified your DNS record. If so, please wait a few hours for it to propagate. If the issue persists, consider adding {domain:s} to /etc/hosts. (If you know what you are doing, use --no-checks to disable those checks.)",
|
|
||||||
"certmanager_domain_unknown": "النطاق مجهول {domain:s}",
|
"certmanager_domain_unknown": "النطاق مجهول {domain:s}",
|
||||||
"certmanager_error_no_A_record": "No DNS 'A' record found for {domain:s}. You need to make your domain name point to your machine to be able to install a Let's Encrypt certificate! (If you know what you are doing, use --no-checks to disable those checks.)",
|
|
||||||
"certmanager_hit_rate_limit": "Too many certificates already issued for exact set of domains {domain:s} recently. Please try again later. See https://letsencrypt.org/docs/rate-limits/ for more details",
|
|
||||||
"certmanager_http_check_timeout": "Timed out when server tried to contact itself through HTTP using public IP address (domain {domain:s} with ip {ip:s}). You may be experiencing hairpinning issue or the firewall/router ahead of your server is misconfigured.",
|
|
||||||
"certmanager_no_cert_file": "تعذرت عملية قراءة شهادة نطاق {domain:s} (الملف : {file:s})",
|
"certmanager_no_cert_file": "تعذرت عملية قراءة شهادة نطاق {domain:s} (الملف : {file:s})",
|
||||||
"certmanager_old_letsencrypt_app_detected": "",
|
|
||||||
"certmanager_self_ca_conf_file_not_found": "Configuration file not found for self-signing authority (file: {file:s})",
|
|
||||||
"certmanager_unable_to_parse_self_CA_name": "Unable to parse name of self-signing authority (file: {file:s})",
|
|
||||||
"custom_app_url_required": "You must provide a URL to upgrade your custom app {app:s}",
|
|
||||||
"custom_appslist_name_required": "You must provide a name for your custom app list",
|
|
||||||
"diagnosis_debian_version_error": "لم نتمكن من العثور على إصدار ديبيان : {error}",
|
|
||||||
"diagnosis_kernel_version_error": "Can't retrieve kernel version: {error}",
|
|
||||||
"diagnosis_monitor_disk_error": "Can't monitor disks: {error}",
|
|
||||||
"diagnosis_monitor_network_error": "Can't monitor network: {error}",
|
|
||||||
"diagnosis_monitor_system_error": "Can't monitor system: {error}",
|
|
||||||
"diagnosis_no_apps": "لم تقم بتنصيب أية تطبيقات بعد",
|
|
||||||
"dnsmasq_isnt_installed": "dnsmasq does not seem to be installed, please run 'apt-get remove bind9 && apt-get install dnsmasq'",
|
|
||||||
"domain_cannot_remove_main": "Cannot remove main domain. Set a new main domain first",
|
|
||||||
"domain_cert_gen_failed": "Unable to generate certificate",
|
|
||||||
"domain_created": "تم إنشاء النطاق",
|
"domain_created": "تم إنشاء النطاق",
|
||||||
"domain_creation_failed": "تعذرت عملية إنشاء النطاق",
|
"domain_creation_failed": "تعذرت عملية إنشاء النطاق",
|
||||||
"domain_deleted": "تم حذف النطاق",
|
"domain_deleted": "تم حذف النطاق",
|
||||||
"domain_deletion_failed": "Unable to delete domain",
|
|
||||||
"domain_dns_conf_is_just_a_recommendation": "This command shows you what is the *recommended* configuration. It does not actually set up the DNS configuration for you. It is your responsability to configure your DNS zone in your registrar according to this recommendation.",
|
|
||||||
"domain_dyndns_already_subscribed": "You've already subscribed to a DynDNS domain",
|
|
||||||
"domain_dyndns_dynette_is_unreachable": "Unable to reach YunoHost dynette, either your YunoHost is not correctly connected to the internet or the dynette server is down. Error: {error}",
|
|
||||||
"domain_dyndns_invalid": "Invalid domain to use with DynDNS",
|
|
||||||
"domain_dyndns_root_unknown": "Unknown DynDNS root domain",
|
|
||||||
"domain_exists": "اسم النطاق موجود مِن قبل",
|
"domain_exists": "اسم النطاق موجود مِن قبل",
|
||||||
"domain_hostname_failed": "Failed to set new hostname",
|
|
||||||
"domain_uninstall_app_first": "One or more apps are installed on this domain. Please uninstall them before proceeding to domain removal",
|
|
||||||
"domain_unknown": "النطاق مجهول",
|
"domain_unknown": "النطاق مجهول",
|
||||||
"domain_zone_exists": "ملف منطقة أسماء النطاقات موجود مِن قبل",
|
|
||||||
"domain_zone_not_found": "DNS zone file not found for domain {:s}",
|
|
||||||
"domains_available": "النطاقات المتوفرة :",
|
"domains_available": "النطاقات المتوفرة :",
|
||||||
"done": "تم",
|
"done": "تم",
|
||||||
"downloading": "عملية التنزيل جارية …",
|
"downloading": "عملية التنزيل جارية …",
|
||||||
"dyndns_could_not_check_provide": "Could not check if {provider:s} can provide {domain:s}.",
|
|
||||||
"dyndns_cron_installed": "The DynDNS cron job has been installed",
|
|
||||||
"dyndns_cron_remove_failed": "Unable to remove the DynDNS cron job",
|
|
||||||
"dyndns_cron_removed": "The DynDNS cron job has been removed",
|
|
||||||
"dyndns_ip_update_failed": "Unable to update IP address on DynDNS",
|
|
||||||
"dyndns_ip_updated": "لقد تم تحديث عنوان الإيبي الخاص بك على نظام أسماء النطاقات الديناميكي",
|
"dyndns_ip_updated": "لقد تم تحديث عنوان الإيبي الخاص بك على نظام أسماء النطاقات الديناميكي",
|
||||||
"dyndns_key_generating": "عملية توليد مفتاح نظام أسماء النطاقات جارية. يمكن للعملية أن تستغرق بعضا من الوقت…",
|
"dyndns_key_generating": "عملية توليد مفتاح نظام أسماء النطاقات جارية. يمكن للعملية أن تستغرق بعضا من الوقت…",
|
||||||
"dyndns_key_not_found": "لم يتم العثور على مفتاح DNS الخاص باسم النطاق هذا",
|
"dyndns_key_not_found": "لم يتم العثور على مفتاح DNS الخاص باسم النطاق هذا",
|
||||||
"dyndns_no_domain_registered": "No domain has been registered with DynDNS",
|
|
||||||
"dyndns_registered": "The DynDNS domain has been registered",
|
|
||||||
"dyndns_registration_failed": "Unable to register DynDNS domain: {error:s}",
|
|
||||||
"dyndns_domain_not_provided": "Dyndns provider {provider:s} cannot provide domain {domain:s}.",
|
|
||||||
"dyndns_unavailable": "Domain {domain:s} is not available.",
|
|
||||||
"executing_command": "Executing command '{command:s}'…",
|
|
||||||
"executing_script": "Executing script '{script:s}'…",
|
|
||||||
"extracting": "عملية فك الضغط جارية …",
|
"extracting": "عملية فك الضغط جارية …",
|
||||||
"field_invalid": "Invalid field '{:s}'",
|
|
||||||
"firewall_reload_failed": "Unable to reload the firewall",
|
|
||||||
"firewall_reloaded": "The firewall has been reloaded",
|
|
||||||
"firewall_rules_cmd_failed": "Some firewall rules commands have failed. For more information, see the log.",
|
|
||||||
"format_datetime_short": "%m/%d/%Y %I:%M %p",
|
|
||||||
"global_settings_bad_choice_for_enum": "Bad value for setting {setting:s}, received {received_type:s}, except {expected_type:s}",
|
|
||||||
"global_settings_bad_type_for_setting": "Bad type for setting {setting:s}, received {received_type:s}, except {expected_type:s}",
|
|
||||||
"global_settings_cant_open_settings": "Failed to open settings file, reason: {reason:s}",
|
|
||||||
"global_settings_cant_serialize_settings": "Failed to serialize settings data, reason: {reason:s}",
|
|
||||||
"global_settings_cant_write_settings": "Failed to write settings file, reason: {reason:s}",
|
|
||||||
"global_settings_key_doesnt_exists": "The key '{settings_key:s}' doesn't exists in the global settings, you can see all the available keys by doing 'yunohost settings list'",
|
|
||||||
"global_settings_reset_success": "Success. Your previous settings have been backuped in {path:s}",
|
|
||||||
"global_settings_setting_example_bool": "Example boolean option",
|
|
||||||
"global_settings_setting_example_enum": "Example enum option",
|
|
||||||
"global_settings_setting_example_int": "Example int option",
|
|
||||||
"global_settings_setting_example_string": "Example string option",
|
|
||||||
"global_settings_unknown_setting_from_settings_file": "Unknown key in settings: '{setting_key:s}', discarding it and save it in /etc/yunohost/unkown_settings.json",
|
|
||||||
"global_settings_unknown_type": "Unexpected situation, the setting {setting:s} appears to have the type {unknown_type:s} but it's not a type supported by the system.",
|
|
||||||
"hook_exec_failed": "Script execution failed: {path:s}",
|
|
||||||
"hook_exec_not_terminated": "Script execution hasn’t terminated: {path:s}",
|
|
||||||
"hook_list_by_invalid": "Invalid property to list hook by",
|
|
||||||
"hook_name_unknown": "Unknown hook name '{name:s}'",
|
|
||||||
"installation_complete": "إكتملت عملية التنصيب",
|
"installation_complete": "إكتملت عملية التنصيب",
|
||||||
"installation_failed": "Installation failed",
|
"main_domain_change_failed": "تعذّر تغيير النطاق الأساسي",
|
||||||
"invalid_url_format": "Invalid URL format",
|
"main_domain_changed": "تم تغيير النطاق الأساسي",
|
||||||
"ip6tables_unavailable": "You cannot play with ip6tables here. You are either in a container or your kernel does not support it",
|
"migrate_tsig_wait": "لننتظر الآن ثلاثة دقائق ريثما يأخذ خادم أسماء النطاقات الديناميكية بعين الاعتبار المفتاح الجديد…",
|
||||||
"iptables_unavailable": "You cannot play with iptables here. You are either in a container or your kernel does not support it",
|
|
||||||
"ldap_init_failed_to_create_admin": "LDAP initialization failed to create admin user",
|
|
||||||
"ldap_initialized": "LDAP has been initialized",
|
|
||||||
"license_undefined": "undefined",
|
|
||||||
"mail_alias_remove_failed": "Unable to remove mail alias '{mail:s}'",
|
|
||||||
"mail_domain_unknown": "Unknown mail address domain '{domain:s}'",
|
|
||||||
"mail_forward_remove_failed": "Unable to remove mail forward '{mail:s}'",
|
|
||||||
"mailbox_used_space_dovecot_down": "Dovecot mailbox service need to be up, if you want to get mailbox used space",
|
|
||||||
"maindomain_change_failed": "Unable to change the main domain",
|
|
||||||
"maindomain_changed": "The main domain has been changed",
|
|
||||||
"migrate_tsig_end": "Migration to hmac-sha512 finished",
|
|
||||||
"migrate_tsig_failed": "Migrating the dyndns domain {domain} to hmac-sha512 failed, rolling back. Error: {error_code} - {error}",
|
|
||||||
"migrate_tsig_start": "Not secure enough key algorithm detected for TSIG signature of domain '{domain}', initiating migration to the more secure one hmac-sha512",
|
|
||||||
"migrate_tsig_wait": "لننتظر الآن 3 دقائق ريثما يأخذ خادم أسماء النطاقات الديناميكية بعين الاعتبار المفتاح الجديد…",
|
|
||||||
"migrate_tsig_wait_2": "دقيقتين …",
|
"migrate_tsig_wait_2": "دقيقتين …",
|
||||||
"migrate_tsig_wait_3": "دقيقة واحدة …",
|
"migrate_tsig_wait_3": "دقيقة واحدة …",
|
||||||
"migrate_tsig_wait_4": "30 ثانية …",
|
"migrate_tsig_wait_4": "30 ثانية …",
|
||||||
"migrate_tsig_not_needed": "You do not appear to use a dyndns domain, so no migration is needed !",
|
|
||||||
"migrations_backward": "Migrating backward.",
|
|
||||||
"migrations_bad_value_for_target": "Invalid number for target argument, available migrations numbers are 0 or {}",
|
|
||||||
"migrations_cant_reach_migration_file": "Can't access migrations files at path %s",
|
|
||||||
"migrations_current_target": "Migration target is {}",
|
|
||||||
"migrations_error_failed_to_load_migration": "ERROR: failed to load migration {number} {name}",
|
|
||||||
"migrations_forward": "Migrating forward",
|
|
||||||
"migrations_loading_migration": "Loading migration {number} {name}…",
|
|
||||||
"migrations_migration_has_failed": "Migration {number} {name} has failed with exception {exception}, aborting",
|
|
||||||
"migrations_no_migrations_to_run": "No migrations to run",
|
|
||||||
"migrations_show_currently_running_migration": "Running migration {number} {name}…",
|
|
||||||
"migrations_show_last_migration": "Last ran migration is {}",
|
|
||||||
"migrations_skip_migration": "جارٍ تجاهل التهجير {id}…",
|
"migrations_skip_migration": "جارٍ تجاهل التهجير {id}…",
|
||||||
"monitor_disabled": "The server monitoring has been disabled",
|
|
||||||
"monitor_enabled": "The server monitoring has been enabled",
|
|
||||||
"monitor_glances_con_failed": "Unable to connect to Glances server",
|
|
||||||
"monitor_not_enabled": "Server monitoring is not enabled",
|
|
||||||
"monitor_period_invalid": "Invalid time period",
|
|
||||||
"monitor_stats_file_not_found": "Statistics file not found",
|
|
||||||
"monitor_stats_no_update": "No monitoring statistics to update",
|
|
||||||
"monitor_stats_period_unavailable": "No available statistics for the period",
|
|
||||||
"mountpoint_unknown": "Unknown mountpoint",
|
|
||||||
"mysql_db_creation_failed": "MySQL database creation failed",
|
|
||||||
"mysql_db_init_failed": "MySQL database init failed",
|
|
||||||
"mysql_db_initialized": "The MySQL database has been initialized",
|
|
||||||
"network_check_mx_ko": "DNS MX record is not set",
|
|
||||||
"network_check_smtp_ko": "Outbound mail (SMTP port 25) seems to be blocked by your network",
|
|
||||||
"network_check_smtp_ok": "Outbound mail (SMTP port 25) is not blocked",
|
|
||||||
"new_domain_required": "You must provide the new main domain",
|
|
||||||
"no_appslist_found": "No app list found",
|
|
||||||
"no_internet_connection": "Server is not connected to the Internet",
|
|
||||||
"no_ipv6_connectivity": "IPv6 connectivity is not available",
|
|
||||||
"no_restore_script": "No restore script found for the app '{app:s}'",
|
|
||||||
"not_enough_disk_space": "Not enough free disk space on '{path:s}'",
|
|
||||||
"package_not_installed": "Package '{pkgname}' is not installed",
|
|
||||||
"package_unexpected_error": "An unexpected error occurred processing the package '{pkgname}'",
|
|
||||||
"package_unknown": "Unknown package '{pkgname}'",
|
|
||||||
"packages_no_upgrade": "لا يوجد هناك أية حزمة بحاجة إلى تحديث",
|
|
||||||
"packages_upgrade_critical_later": "Critical packages ({packages:s}) will be upgraded later",
|
|
||||||
"packages_upgrade_failed": "Unable to upgrade all of the packages",
|
|
||||||
"path_removal_failed": "Unable to remove path {:s}",
|
|
||||||
"pattern_backup_archive_name": "Must be a valid filename with max 30 characters, and alphanumeric and -_. characters only",
|
|
||||||
"pattern_domain": "يتوجب أن يكون إسم نطاق صالح (مثل my-domain.org)",
|
"pattern_domain": "يتوجب أن يكون إسم نطاق صالح (مثل my-domain.org)",
|
||||||
"pattern_email": "يتوجب أن يكون عنوان بريد إلكتروني صالح (مثل someone@domain.org)",
|
"pattern_email": "يتوجب أن يكون عنوان بريد إلكتروني صالح (مثل someone@domain.org)",
|
||||||
"pattern_firstname": "Must be a valid first name",
|
|
||||||
"pattern_lastname": "Must be a valid last name",
|
|
||||||
"pattern_listname": "Must be alphanumeric and underscore characters only",
|
|
||||||
"pattern_mailbox_quota": "Must be a size with b/k/M/G/T suffix or 0 to disable the quota",
|
|
||||||
"pattern_password": "يتوجب أن تكون مكونة من 3 حروف على الأقل",
|
"pattern_password": "يتوجب أن تكون مكونة من 3 حروف على الأقل",
|
||||||
"pattern_port": "يجب أن يكون رقم منفذ صالح (مثال 0-65535)",
|
|
||||||
"pattern_port_or_range": "Must be a valid port number (i.e. 0-65535) or range of ports (e.g. 100:200)",
|
|
||||||
"pattern_positive_number": "يجب أن يكون عددا إيجابيا",
|
"pattern_positive_number": "يجب أن يكون عددا إيجابيا",
|
||||||
"pattern_username": "Must be lower-case alphanumeric and underscore characters only",
|
|
||||||
"port_already_closed": "Port {port:d} is already closed for {ip_version:s} connections",
|
|
||||||
"port_already_opened": "Port {port:d} is already opened for {ip_version:s} connections",
|
|
||||||
"port_available": "المنفذ {port:d} متوفر",
|
|
||||||
"port_unavailable": "Port {port:d} is not available",
|
|
||||||
"restore_action_required": "You must specify something to restore",
|
|
||||||
"restore_already_installed_app": "An app is already installed with the id '{app:s}'",
|
|
||||||
"restore_app_failed": "Unable to restore the app '{app:s}'",
|
|
||||||
"restore_cleaning_failed": "Unable to clean-up the temporary restoration directory",
|
|
||||||
"restore_complete": "Restore complete",
|
|
||||||
"restore_confirm_yunohost_installed": "Do you really want to restore an already installed system? [{answers:s}]",
|
|
||||||
"restore_extracting": "جارٍ فك الضغط عن الملفات التي نحتاجها من النسخة الاحتياطية…",
|
"restore_extracting": "جارٍ فك الضغط عن الملفات التي نحتاجها من النسخة الاحتياطية…",
|
||||||
"restore_failed": "Unable to restore the system",
|
|
||||||
"restore_hook_unavailable": "Restoration script for '{part:s}' not available on your system and not in the archive either",
|
|
||||||
"restore_may_be_not_enough_disk_space": "Your system seems not to have enough disk space (freespace: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)",
|
|
||||||
"restore_mounting_archive": "تنصيب النسخة الإحتياطية على المسار '{path:s}'",
|
|
||||||
"restore_not_enough_disk_space": "Not enough disk space (freespace: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)",
|
|
||||||
"restore_nothings_done": "Nothing has been restored",
|
|
||||||
"restore_removing_tmp_dir_failed": "Unable to remove an old temporary directory",
|
|
||||||
"restore_running_app_script": "Running restore script of app '{app:s}'…",
|
|
||||||
"restore_running_hooks": "Running restoration hooks…",
|
|
||||||
"restore_system_part_failed": "Unable to restore the '{part:s}' system part",
|
|
||||||
"server_shutdown": "سوف ينطفئ الخادوم",
|
"server_shutdown": "سوف ينطفئ الخادوم",
|
||||||
"server_shutdown_confirm": "سوف ينطفئ الخادوم حالا. متأكد ؟ [{answers:s}]",
|
"server_shutdown_confirm": "سوف ينطفئ الخادوم حالا. متأكد ؟ [{answers:s}]",
|
||||||
"server_reboot": "سيعاد تشغيل الخادوم",
|
"server_reboot": "سيعاد تشغيل الخادوم",
|
||||||
"server_reboot_confirm": "سيعاد تشغيل الخادوم في الحين. هل أنت متأكد ؟ [{answers:s}]",
|
"server_reboot_confirm": "سيعاد تشغيل الخادوم في الحين. هل أنت متأكد ؟ [{answers:s}]",
|
||||||
"service_add_failed": "تعذرت إضافة خدمة '{service:s}'",
|
"service_add_failed": "تعذرت إضافة خدمة '{service:s}'",
|
||||||
"service_added": "The service '{service:s}' has been added",
|
|
||||||
"service_already_started": "Service '{service:s}' has already been started",
|
|
||||||
"service_already_stopped": "إنّ خدمة '{service:s}' متوقفة مِن قبلُ",
|
"service_already_stopped": "إنّ خدمة '{service:s}' متوقفة مِن قبلُ",
|
||||||
"service_cmd_exec_failed": "Unable to execute command '{command:s}'",
|
"service_disabled": "لن يتم إطلاق خدمة '{service:s}' أثناء بداية تشغيل النظام.",
|
||||||
"service_conf_file_backed_up": "The configuration file '{conf}' has been backed up to '{backup}'",
|
|
||||||
"service_conf_file_copy_failed": "Unable to copy the new configuration file '{new}' to '{conf}'",
|
|
||||||
"service_conf_file_kept_back": "The configuration file '{conf}' is expected to be deleted by service {service} but has been kept back.",
|
|
||||||
"service_conf_file_manually_modified": "The configuration file '{conf}' has been manually modified and will not be updated",
|
|
||||||
"service_conf_file_manually_removed": "The configuration file '{conf}' has been manually removed and will not be created",
|
|
||||||
"service_conf_file_remove_failed": "Unable to remove the configuration file '{conf}'",
|
|
||||||
"service_conf_file_removed": "The configuration file '{conf}' has been removed",
|
|
||||||
"service_conf_file_updated": "The configuration file '{conf}' has been updated",
|
|
||||||
"service_conf_new_managed_file": "The configuration file '{conf}' is now managed by the service {service}.",
|
|
||||||
"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}'",
|
|
||||||
"service_disable_failed": "",
|
|
||||||
"service_disabled": "تم تعطيل خدمة '{service:s}'",
|
|
||||||
"service_enable_failed": "",
|
|
||||||
"service_enabled": "تم تنشيط خدمة '{service:s}'",
|
"service_enabled": "تم تنشيط خدمة '{service:s}'",
|
||||||
"service_no_log": "ليس لخدمة '{service:s}' أي سِجلّ للعرض",
|
|
||||||
"service_regenconf_dry_pending_applying": "Checking pending configuration which would have been applied for service '{service}'...",
|
|
||||||
"service_regenconf_failed": "Unable to regenerate the configuration for service(s): {services}",
|
|
||||||
"service_regenconf_pending_applying": "Applying pending configuration for service '{service}'...",
|
|
||||||
"service_remove_failed": "Unable to remove service '{service:s}'",
|
|
||||||
"service_removed": "تمت إزالة خدمة '{service:s}'",
|
"service_removed": "تمت إزالة خدمة '{service:s}'",
|
||||||
"service_start_failed": "",
|
|
||||||
"service_started": "تم إطلاق تشغيل خدمة '{service:s}'",
|
"service_started": "تم إطلاق تشغيل خدمة '{service:s}'",
|
||||||
"service_status_failed": "Unable to determine status of service '{service:s}'",
|
|
||||||
"service_stop_failed": "",
|
|
||||||
"service_stopped": "تمّ إيقاف خدمة '{service:s}'",
|
"service_stopped": "تمّ إيقاف خدمة '{service:s}'",
|
||||||
"service_unknown": "Unknown service '{service:s}'",
|
|
||||||
"ssowat_conf_generated": "The SSOwat configuration has been generated",
|
|
||||||
"ssowat_conf_updated": "The SSOwat configuration has been updated",
|
|
||||||
"ssowat_persistent_conf_read_error": "Error while reading SSOwat persistent configuration: {error:s}. Edit /etc/ssowat/conf.json.persistent file to fix the JSON syntax",
|
|
||||||
"ssowat_persistent_conf_write_error": "Error while saving SSOwat persistent configuration: {error:s}. Edit /etc/ssowat/conf.json.persistent file to fix the JSON syntax",
|
|
||||||
"system_upgraded": "تمت عملية ترقية النظام",
|
"system_upgraded": "تمت عملية ترقية النظام",
|
||||||
"system_username_exists": "Username already exists in the system users",
|
|
||||||
"unbackup_app": "App '{app:s}' will not be saved",
|
|
||||||
"unexpected_error": "An unexpected error occured",
|
|
||||||
"unit_unknown": "Unknown unit '{unit:s}'",
|
|
||||||
"unlimit": "دون تحديد الحصة",
|
"unlimit": "دون تحديد الحصة",
|
||||||
"unrestore_app": "App '{app:s}' will not be restored",
|
|
||||||
"update_cache_failed": "Unable to update APT cache",
|
|
||||||
"updating_apt_cache": "جارٍ جلب قائمة حُزم النظام المحدّثة المتوفرة…",
|
"updating_apt_cache": "جارٍ جلب قائمة حُزم النظام المحدّثة المتوفرة…",
|
||||||
"upgrade_complete": "إكتملت عملية الترقية و التحديث",
|
"upgrade_complete": "اكتملت عملية الترقية و التحديث",
|
||||||
"upgrading_packages": "عملية ترقية الحُزم جارية …",
|
"upgrading_packages": "عملية ترقية الحُزم جارية …",
|
||||||
"upnp_dev_not_found": "No UPnP device found",
|
|
||||||
"upnp_disabled": "تم تعطيل UPnP",
|
"upnp_disabled": "تم تعطيل UPnP",
|
||||||
"upnp_enabled": "UPnP has been enabled",
|
|
||||||
"upnp_port_open_failed": "Unable to open UPnP ports",
|
|
||||||
"user_created": "تم إنشاء المستخدم",
|
"user_created": "تم إنشاء المستخدم",
|
||||||
"user_creation_failed": "Unable to create user",
|
|
||||||
"user_deleted": "تم حذف المستخدم",
|
"user_deleted": "تم حذف المستخدم",
|
||||||
"user_deletion_failed": "لا يمكن حذف المستخدم",
|
"user_deletion_failed": "لا يمكن حذف المستخدم",
|
||||||
"user_home_creation_failed": "Unable to create user home folder",
|
|
||||||
"user_info_failed": "Unable to retrieve user information",
|
|
||||||
"user_unknown": "المستخدم {user:s} مجهول",
|
"user_unknown": "المستخدم {user:s} مجهول",
|
||||||
"user_update_failed": "لا يمكن تحديث المستخدم",
|
"user_update_failed": "لا يمكن تحديث المستخدم",
|
||||||
"user_updated": "تم تحديث المستخدم",
|
"user_updated": "تم تحديث المستخدم",
|
||||||
"yunohost_already_installed": "YunoHost is already installed",
|
|
||||||
"yunohost_ca_creation_failed": "تعذرت عملية إنشاء هيئة الشهادات",
|
"yunohost_ca_creation_failed": "تعذرت عملية إنشاء هيئة الشهادات",
|
||||||
"yunohost_ca_creation_success": "تم إنشاء هيئة الشهادات المحلية.",
|
"yunohost_ca_creation_success": "تم إنشاء هيئة الشهادات المحلية.",
|
||||||
"yunohost_configured": "YunoHost has been configured",
|
|
||||||
"yunohost_installing": "عملية تنصيب يونوهوست جارية …",
|
"yunohost_installing": "عملية تنصيب يونوهوست جارية …",
|
||||||
"yunohost_not_installed": "إنَّ واي يونوهوست ليس مُنَصَّب أو هو مثبت حاليا بشكل خاطئ. قم بتنفيذ الأمر 'yunohost tools postinstall'",
|
"yunohost_not_installed": "إنَّ واي يونوهوست ليس مُنَصَّب أو هو مثبت حاليا بشكل خاطئ. قم بتنفيذ الأمر 'yunohost tools postinstall'",
|
||||||
"migration_description_0003_migrate_to_stretch": "تحديث النظام إلى ديبيان ستريتش و واي يونوهوست 3.0",
|
"migration_description_0003_migrate_to_stretch": "تحديث النظام إلى ديبيان ستريتش و واي يونوهوست 3.0",
|
||||||
"migration_0003_patching_sources_list": "عملية تصحيح ملف المصادر sources.lists جارية…",
|
"migration_0003_patching_sources_list": "عملية تصحيح ملف المصادر sources.lists جارية…",
|
||||||
"migration_0003_main_upgrade": "بداية عملية التحديث الأساسية…",
|
"migration_0003_main_upgrade": "بداية عملية التحديث الأساسية…",
|
||||||
"migration_0003_fail2ban_upgrade": "بداية عملية تحديث fail2ban…",
|
"migration_0003_fail2ban_upgrade": "بداية عملية تحديث Fail2Ban…",
|
||||||
"migration_0003_not_jessie": "إن توزيعة ديبيان الحالية تختلف عن جيسي !",
|
"migration_0003_not_jessie": "إن توزيعة ديبيان الحالية تختلف عن جيسي !",
|
||||||
"migration_description_0002_migrate_to_tsig_sha256": "يقوم بتحسين أمان TSIG لنظام أسماء النطاقات الديناميكة باستخدام SHA512 بدلًا مِن MD5",
|
"migration_description_0002_migrate_to_tsig_sha256": "يقوم بتحسين أمان TSIG لنظام أسماء النطاقات الديناميكة باستخدام SHA512 بدلًا مِن MD5",
|
||||||
"migration_0003_backward_impossible": "لا يُمكن إلغاء عملية الإنتقال إلى ستريتش.",
|
|
||||||
"migration_0003_system_not_fully_up_to_date": "إنّ نظامك غير مُحدَّث بعدُ لذا يرجى القيام بتحديث عادي أولا قبل إطلاق إجراء الإنتقال إلى نظام ستريتش.",
|
"migration_0003_system_not_fully_up_to_date": "إنّ نظامك غير مُحدَّث بعدُ لذا يرجى القيام بتحديث عادي أولا قبل إطلاق إجراء الإنتقال إلى نظام ستريتش.",
|
||||||
"migrations_list_conflict_pending_done": "لا يمكنك استخدام --previous و --done معًا على نفس سطر الأوامر.",
|
"migrations_list_conflict_pending_done": "لا يمكنك استخدام --previous و --done معًا على نفس سطر الأوامر.",
|
||||||
"service_description_avahi-daemon": "يسمح لك بالنفاذ إلى خادومك عبر الشبكة المحلية باستخدام yunohost.local",
|
"service_description_avahi-daemon": "يسمح لك بالنفاذ إلى خادومك عبر الشبكة المحلية باستخدام yunohost.local",
|
||||||
"service_description_glances": "يقوم بمراقبة معلومات النظام على خادومك",
|
|
||||||
"service_description_metronome": "يُدير حسابات الدردشة الفورية XMPP",
|
"service_description_metronome": "يُدير حسابات الدردشة الفورية XMPP",
|
||||||
"service_description_nginx": "يقوم بتوفير النفاذ و السماح بالوصول إلى كافة مواقع الويب المستضافة على خادومك",
|
"service_description_nginx": "يقوم بتوفير النفاذ و السماح بالوصول إلى كافة مواقع الويب المستضافة على خادومك",
|
||||||
"service_description_php5-fpm": "يقوم بتشغيل تطبيقات الـ PHP مع خادوم الويب nginx",
|
|
||||||
"service_description_postfix": "يقوم بإرسال و تلقي الرسائل البريدية الإلكترونية",
|
"service_description_postfix": "يقوم بإرسال و تلقي الرسائل البريدية الإلكترونية",
|
||||||
"service_description_yunohost-api": "يقوم بإدارة التفاعلات ما بين واجهة الويب لواي يونوهوست و النظام",
|
"service_description_yunohost-api": "يقوم بإدارة التفاعلات ما بين واجهة الويب لواي يونوهوست و النظام",
|
||||||
"log_category_404": "فئةالسجل '{category}' لا وجود لها",
|
"log_category_404": "فئةالسجل '{category}' لا وجود لها",
|
||||||
"log_app_fetchlist": "إضافة قائمة للتطبيقات",
|
|
||||||
"log_app_removelist": "حذف قائمة للتطبيقات",
|
|
||||||
"log_app_change_url": "تعديل رابط تطبيق '{}'",
|
"log_app_change_url": "تعديل رابط تطبيق '{}'",
|
||||||
"log_app_install": "تنصيب تطبيق '{}'",
|
"log_app_install": "تنصيب تطبيق '{}'",
|
||||||
"log_app_remove": "حذف تطبيق '{}'",
|
"log_app_remove": "حذف تطبيق '{}'",
|
||||||
|
@ -400,11 +121,10 @@
|
||||||
"log_letsencrypt_cert_install": "تنصيب شهادة Let’s Encrypt على النطاق '{}'",
|
"log_letsencrypt_cert_install": "تنصيب شهادة Let’s Encrypt على النطاق '{}'",
|
||||||
"log_selfsigned_cert_install": "تنصيب شهادة موقَّعَة ذاتيا على اسم النطاق '{}'",
|
"log_selfsigned_cert_install": "تنصيب شهادة موقَّعَة ذاتيا على اسم النطاق '{}'",
|
||||||
"log_letsencrypt_cert_renew": "تجديد شهادة Let's Encrypt لـ '{}'",
|
"log_letsencrypt_cert_renew": "تجديد شهادة Let's Encrypt لـ '{}'",
|
||||||
"log_service_enable": "تنشيط خدمة '{}'",
|
|
||||||
"log_user_create": "إضافة المستخدم '{}'",
|
"log_user_create": "إضافة المستخدم '{}'",
|
||||||
"log_user_delete": "حذف المستخدم '{}'",
|
"log_user_delete": "حذف المستخدم '{}'",
|
||||||
"log_user_update": "تحديث معلومات المستخدم '{}'",
|
"log_user_update": "تحديث معلومات المستخدم '{}'",
|
||||||
"log_tools_maindomain": "جعل '{}' كنطاق أساسي",
|
"log_domain_main_domain": "جعل '{}' كنطاق أساسي",
|
||||||
"log_tools_upgrade": "تحديث حُزم ديبيان",
|
"log_tools_upgrade": "تحديث حُزم ديبيان",
|
||||||
"log_tools_shutdown": "إطفاء الخادم",
|
"log_tools_shutdown": "إطفاء الخادم",
|
||||||
"log_tools_reboot": "إعادة تشغيل الخادم",
|
"log_tools_reboot": "إعادة تشغيل الخادم",
|
||||||
|
@ -412,11 +132,11 @@
|
||||||
"service_description_dnsmasq": "مُكلَّف بتحليل أسماء النطاقات (DNS)",
|
"service_description_dnsmasq": "مُكلَّف بتحليل أسماء النطاقات (DNS)",
|
||||||
"service_description_mysql": "يقوم بتخزين بيانات التطبيقات (قواعد بيانات SQL)",
|
"service_description_mysql": "يقوم بتخزين بيانات التطبيقات (قواعد بيانات SQL)",
|
||||||
"service_description_rspamd": "يقوم بتصفية البريد المزعج و إدارة ميزات أخرى للبريد",
|
"service_description_rspamd": "يقوم بتصفية البريد المزعج و إدارة ميزات أخرى للبريد",
|
||||||
"service_description_yunohost-firewall": "يُدير فتح وإغلاق منافذ الإتصال إلى الخدمات",
|
"service_description_yunohost-firewall": "يُدير فتح وإغلاق منافذ الاتصال إلى الخدمات",
|
||||||
"users_available": "المستخدمون المتوفرون:",
|
"users_available": "المستخدمون المتوفرون:",
|
||||||
"aborting": "إلغاء.",
|
"aborting": "إلغاء.",
|
||||||
"admin_password_too_long": "يرجى اختيار كلمة سرية أقصر مِن 127 حرف",
|
"admin_password_too_long": "يرجى اختيار كلمة سرية أقصر مِن 127 حرف",
|
||||||
"app_not_upgraded": "لم يتم تحديث التطبيقات التالية: {apps}",
|
"app_not_upgraded": "",
|
||||||
"app_start_install": "جارٍ تثبيت التطبيق {app}…",
|
"app_start_install": "جارٍ تثبيت التطبيق {app}…",
|
||||||
"app_start_remove": "جارٍ حذف التطبيق {app}…",
|
"app_start_remove": "جارٍ حذف التطبيق {app}…",
|
||||||
"app_start_restore": "جارٍ استرجاع التطبيق {app}…",
|
"app_start_restore": "جارٍ استرجاع التطبيق {app}…",
|
||||||
|
@ -425,23 +145,32 @@
|
||||||
"ask_new_path": "مسار جديد",
|
"ask_new_path": "مسار جديد",
|
||||||
"global_settings_setting_security_password_admin_strength": "قوة الكلمة السرية الإدارية",
|
"global_settings_setting_security_password_admin_strength": "قوة الكلمة السرية الإدارية",
|
||||||
"global_settings_setting_security_password_user_strength": "قوة الكلمة السرية للمستخدم",
|
"global_settings_setting_security_password_user_strength": "قوة الكلمة السرية للمستخدم",
|
||||||
"log_app_addaccess": "إضافة ترخيص بالنفاذ إلى '{}'",
|
|
||||||
"password_too_simple_1": "يجب أن يكون طول الكلمة السرية على الأقل 8 حروف",
|
"password_too_simple_1": "يجب أن يكون طول الكلمة السرية على الأقل 8 حروف",
|
||||||
"service_description_php7.0-fpm": "يُشغّل التطبيقات المكتوبة بلغة الـ PHP على Nginx",
|
"service_description_php7.0-fpm": "يُشغّل التطبيقات المكتوبة بلغة الـ PHP على NGINX",
|
||||||
"updating_app_lists": "جارٍ جلب التحديثات المتوفرة الخاصة بالتطبيقات…",
|
"already_up_to_date": "كل شيء على ما يرام. ليس هناك ما يتطلّب تحديثًا.",
|
||||||
"already_up_to_date": "كل شيء على ما يرام! ليس هناك ما يتطلّب تحديثًا!",
|
|
||||||
"service_description_nslcd": "يدير اتصال متسخدمي واي يونوهوست عبر طرفية سطر الأوامر",
|
"service_description_nslcd": "يدير اتصال متسخدمي واي يونوهوست عبر طرفية سطر الأوامر",
|
||||||
"service_description_slapd": "يخزّن المستخدمين والنطاقات والمعلومات المتعلقة بها",
|
"service_description_slapd": "يخزّن المستخدمين والنطاقات والمعلومات المتعلقة بها",
|
||||||
"service_reloaded": "تم إعادة تحميل خدمة '{service:s}'",
|
"service_reloaded": "تم إعادة تشغيل خدمة '{service:s}'",
|
||||||
"service_restarted": "تم إعادة تشغيل خدمة '{service:s}'",
|
"service_restarted": "تم إعادة تشغيل خدمة '{service:s}'",
|
||||||
"group_unknown": "الفريق {group:s} مجهول",
|
"group_unknown": "الفريق {group:s} مجهول",
|
||||||
"group_deletion_failed": "فشلت عملية حذف الفريق '{group}'",
|
"group_deletion_failed": "فشلت عملية حذف الفريق '{group}': {error}",
|
||||||
"group_deleted": "تم حذف الفريق '{group}'",
|
"group_deleted": "تم حذف الفريق '{group}'",
|
||||||
"group_created": "تم إنشاء الفريق '{group}' بنجاح",
|
"group_created": "تم إنشاء الفريق '{group}'",
|
||||||
"group_name_already_exist": "الفريق {name:s} موجود بالفعل",
|
|
||||||
"error_when_removing_sftpuser_group": "حدث خطأ أثناء محاولة حذف فريق sftpusers",
|
|
||||||
"dyndns_could_not_check_available": "لا يمكن التحقق مِن أنّ {domain:s} متوفر على {provider:s}.",
|
"dyndns_could_not_check_available": "لا يمكن التحقق مِن أنّ {domain:s} متوفر على {provider:s}.",
|
||||||
"backup_mount_archive_for_restore": "جارٍ تهيئة النسخة الاحتياطية للاسترجاع…",
|
"backup_mount_archive_for_restore": "جارٍ تهيئة النسخة الاحتياطية للاسترجاع…",
|
||||||
"root_password_replaced_by_admin_password": "لقد تم استبدال كلمة سر الجذر root بالكلمة الإدارية لـ admin.",
|
"root_password_replaced_by_admin_password": "لقد تم استبدال كلمة سر الجذر root بالكلمة الإدارية لـ admin.",
|
||||||
"app_upgrade_stopped": "لقد تم إلغاء تحديث كافة التطبيقات لتجنب حادث بسبب فشل تحديث التطبيق السابق"
|
"app_action_broke_system": "يبدو أنّ هذا الإجراء أدّى إلى تحطيم هذه الخدمات المهمة: {services}",
|
||||||
|
"diagnosis_basesystem_host": "هذا الخادم يُشغّل ديبيان {debian_version}",
|
||||||
|
"diagnosis_basesystem_kernel": "هذا الخادم يُشغّل نواة لينكس {kernel_version}",
|
||||||
|
"diagnosis_basesystem_ynh_single_version": "{package} الإصدار: {version} ({repo})",
|
||||||
|
"diagnosis_basesystem_ynh_main_version": "هذا الخادم يُشغّل YunoHost {main_version} ({repo})",
|
||||||
|
"diagnosis_everything_ok": "كل شيء على ما يرام في {category}!",
|
||||||
|
"diagnosis_ip_connected_ipv4": "الخادم مُتّصل بالإنترنت عبر IPv4!",
|
||||||
|
"diagnosis_ip_connected_ipv6": "الخادم مُتّصل بالإنترنت عبر IPv6!",
|
||||||
|
"diagnosis_ip_not_connected_at_all": "يبدو أنّ الخادم غير مُتّصل بتاتا بالإنترنت!؟",
|
||||||
|
"app_install_failed": "لا يمكن تنصيب {app}: {error}",
|
||||||
|
"apps_already_up_to_date": "كافة التطبيقات مُحدّثة",
|
||||||
|
"app_remove_after_failed_install": "جارٍ حذف التطبيق بعدما فشل تنصيبها…",
|
||||||
|
"apps_catalog_updating": "جارٍ تحديث فهرس التطبيقات…",
|
||||||
|
"apps_catalog_update_success": "تم تحديث فهرس التطبيقات!"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
{}
|
{
|
||||||
|
"password_too_simple_1": "পাসওয়ার্ডটি কমপক্ষে 8 টি অক্ষরের দীর্ঘ হওয়া দরকার"
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
{}
|
{}
|
642
locales/ca.json
642
locales/ca.json
|
@ -1,113 +1,88 @@
|
||||||
{
|
{
|
||||||
"action_invalid": "Acció '{action:s}' invàlida",
|
"action_invalid": "Acció '{action:s}' invàlida",
|
||||||
"admin_password": "Contrasenya d'administració",
|
"admin_password": "Contrasenya d'administració",
|
||||||
"admin_password_change_failed": "No s'ha pogut canviar la contrasenya",
|
"admin_password_change_failed": "No es pot canviar la contrasenya",
|
||||||
"admin_password_changed": "S'ha canviat la contrasenya d'administració",
|
"admin_password_changed": "S'ha canviat la contrasenya d'administració",
|
||||||
"app_already_installed": "{app:s} ja està instal·lada",
|
"app_already_installed": "{app:s} ja està instal·lada",
|
||||||
"app_already_installed_cant_change_url": "Aquesta aplicació ja està instal·lada. La URL no és pot canviar únicament amb aquesta funció. Mireu a \"app changeurl\" si està disponible.",
|
"app_already_installed_cant_change_url": "Aquesta aplicació ja està instal·lada. La URL no és pot canviar únicament amb aquesta funció. Mireu a \"app changeurl\" si està disponible.",
|
||||||
"app_already_up_to_date": "{app:s} ja està actualitzada",
|
"app_already_up_to_date": "{app:s} ja està actualitzada",
|
||||||
"app_argument_choice_invalid": "Aquesta opció no és vàlida per l'argument '{name:s}', ha de ser una de {choices:s}",
|
"app_argument_choice_invalid": "Utilitzeu una de les opcions «{choices:s}» per l'argument «{name:s}»",
|
||||||
"app_argument_invalid": "Valor invàlid per l'argument '{name:s}':{error:s}",
|
"app_argument_invalid": "Escolliu un valor vàlid per l'argument «{name:s}»: {error:s}",
|
||||||
"app_argument_required": "Es necessita l'argument '{name:s}'",
|
"app_argument_required": "Es necessita l'argument '{name:s}'",
|
||||||
"app_change_no_change_url_script": "L'aplicació {app_name:s} encara no permet canviar la seva URL, es possible que s'hagi d'actualitzar.",
|
"app_change_url_failed_nginx_reload": "No s'ha pogut tornar a carregar NGINX. Aquí teniu el resultat de \"nginx -t\":\n{nginx_errors:s}",
|
||||||
"app_change_url_failed_nginx_reload": "No s'ha pogut tornar a carregar nginx. Aquí teniu el resultat de \"nginx -t\":\n{nginx_errors:s}",
|
|
||||||
"app_change_url_identical_domains": "L'antic i el nou domini/camí són idèntics ('{domain:s}{path:s}'), no hi ha res per fer.",
|
"app_change_url_identical_domains": "L'antic i el nou domini/camí són idèntics ('{domain:s}{path:s}'), no hi ha res per fer.",
|
||||||
"app_change_url_no_script": "Aquesta aplicació '{app_name:s}' encara no permet modificar la URL. Potser s'ha d'actualitzar l'aplicació.",
|
"app_change_url_no_script": "L'aplicació '{app_name:s}' encara no permet modificar la URL. Potser s'ha d'actualitzar.",
|
||||||
"app_change_url_success": "La URL de {app:s} s'ha canviat correctament a {domain:s}{path:s}",
|
"app_change_url_success": "La URL de {app:s} ara és {domain:s}{path:s}",
|
||||||
"app_extraction_failed": "No s'han pogut extreure els fitxers d'instal·lació",
|
"app_extraction_failed": "No s'han pogut extreure els fitxers d'instal·lació",
|
||||||
"app_id_invalid": "Id de l'aplicació incorrecte",
|
"app_id_invalid": "ID de l'aplicació incorrecte",
|
||||||
"app_incompatible": "L'aplicació {app} no és compatible amb la teva versió de YunoHost",
|
"app_install_files_invalid": "Aquests fitxers no es poden instal·lar",
|
||||||
"app_install_files_invalid": "Fitxers d'instal·lació invàlids",
|
"app_make_default_location_already_used": "No es pot fer l'aplicació '{app}' per defecte en el domini «{domain}» ja que ja és utilitzat per una altra aplicació '{other_app}'",
|
||||||
"app_location_already_used": "L'aplicació '{app}' ja està instal·lada en aquest camí ({path})",
|
"app_location_unavailable": "Aquesta URL no està disponible o entra en conflicte amb aplicacions ja instal·lades:\n{apps:s}",
|
||||||
"app_make_default_location_already_used": "No es pot fer l'aplicació '{app}' per defecte en el domini {domain} ja que ja és utilitzat per una altra aplicació '{other_app}'",
|
"app_manifest_invalid": "Hi ha algun error amb el manifest de l'aplicació: {error}",
|
||||||
"app_location_install_failed": "No s'ha pogut instal·lar l'aplicació en aquest camí ja que entra en conflicte amb l'aplicació '{other_app}' ja instal·lada a '{other_path}'",
|
|
||||||
"app_location_unavailable": "Aquesta url no està disponible o entra en conflicte amb aplicacions ja instal·lades:\n{apps:s}",
|
|
||||||
"app_manifest_invalid": "Manifest d'aplicació incorrecte: {error}",
|
|
||||||
"app_no_upgrade": "No hi ha cap aplicació per actualitzar",
|
|
||||||
"app_not_correctly_installed": "{app:s} sembla estar mal instal·lada",
|
"app_not_correctly_installed": "{app:s} sembla estar mal instal·lada",
|
||||||
"app_not_installed": "L'aplicació «{app:s}» no està instal·lada. Aquí hi ha la llista d'aplicacions instal·lades: {all_apps}",
|
"app_not_installed": "No s'ha trobat l'aplicació «{app:s}» en la llista d'aplicacions instal·lades: {all_apps}",
|
||||||
"app_not_properly_removed": "{app:s} no s'ha pogut suprimir correctament",
|
"app_not_properly_removed": "{app:s} no s'ha pogut suprimir correctament",
|
||||||
"app_package_need_update": "El paquet de l'aplicació {app} ha de ser actualitzat per poder seguir els canvis de YunoHost",
|
|
||||||
"app_removed": "{app:s} ha estat suprimida",
|
"app_removed": "{app:s} ha estat suprimida",
|
||||||
"app_requirements_checking": "Verificació dels paquets requerits per {app}…",
|
"app_requirements_checking": "Verificació dels paquets requerits per {app}…",
|
||||||
"app_requirements_failed": "No es poden satisfer els requeriments per {app}: {error}",
|
|
||||||
"app_requirements_unmeet": "No es compleixen els requeriments per {app}, el paquet {pkgname} ({version}) ha de ser {spec}",
|
"app_requirements_unmeet": "No es compleixen els requeriments per {app}, el paquet {pkgname} ({version}) ha de ser {spec}",
|
||||||
"app_sources_fetch_failed": "No s'han pogut carregar els fitxers font, l'URL és correcta?",
|
"app_sources_fetch_failed": "No s'han pogut carregar els fitxers font, l'URL és correcta?",
|
||||||
"app_unknown": "Aplicació desconeguda",
|
"app_unknown": "Aplicació desconeguda",
|
||||||
"app_unsupported_remote_type": "El tipus remot utilitzat per l'aplicació no està suportat",
|
"app_unsupported_remote_type": "El tipus remot utilitzat per l'aplicació no està suportat",
|
||||||
"app_upgrade_app_name": "Actualitzant l'aplicació {app}…",
|
"app_upgrade_app_name": "Actualitzant {app}…",
|
||||||
"app_upgrade_failed": "No s'ha pogut actualitzar {app:s}",
|
"app_upgrade_failed": "No s'ha pogut actualitzar {app:s}: {error}",
|
||||||
"app_upgrade_some_app_failed": "No s'han pogut actualitzar algunes aplicacions",
|
"app_upgrade_some_app_failed": "No s'han pogut actualitzar algunes aplicacions",
|
||||||
"app_upgraded": "{app:s} ha estat actualitzada",
|
"app_upgraded": "S'ha actualitzat {app:s}",
|
||||||
"appslist_corrupted_json": "No s'han pogut carregar les llistes d'aplicacions. Sembla que {filename:s} està danyat.",
|
"ask_email": "Adreça de correu electrònic",
|
||||||
"appslist_could_not_migrate": "No s'ha pogut migrar la llista d'aplicacions {appslist:s}! No s'ha pogut analitzar la URL... L'antic cronjob s'ha guardat a {bkp_file:s}.",
|
|
||||||
"appslist_fetched": "S'ha descarregat la llista d'aplicacions {appslist:s} correctament",
|
|
||||||
"appslist_migrating": "Migrant la llista d'aplicacions {appslist:s}…",
|
|
||||||
"appslist_name_already_tracked": "Ja hi ha una llista d'aplicacions registrada amb el nom {name:s}.",
|
|
||||||
"appslist_removed": "S'ha eliminat la llista d'aplicacions {appslist:s}",
|
|
||||||
"appslist_retrieve_bad_format": "L'arxiu obtingut per la llista d'aplicacions {appslist:s} no és vàlid",
|
|
||||||
"appslist_retrieve_error": "No s'ha pogut obtenir la llista d'aplicacions remota {appslist:s}: {error:s}",
|
|
||||||
"appslist_unknown": "La llista d'aplicacions {appslist:s} es desconeguda.",
|
|
||||||
"appslist_url_already_tracked": "Ja hi ha una llista d'aplicacions registrada amb al URL {url:s}.",
|
|
||||||
"ask_current_admin_password": "Contrasenya d'administrador actual",
|
|
||||||
"ask_email": "Correu electrònic",
|
|
||||||
"ask_firstname": "Nom",
|
"ask_firstname": "Nom",
|
||||||
"ask_lastname": "Cognom",
|
"ask_lastname": "Cognom",
|
||||||
"ask_list_to_remove": "Llista per a suprimir",
|
|
||||||
"ask_main_domain": "Domini principal",
|
"ask_main_domain": "Domini principal",
|
||||||
"ask_new_admin_password": "Nova contrasenya d'administrador",
|
"ask_new_admin_password": "Nova contrasenya d'administrador",
|
||||||
"ask_password": "Contrasenya",
|
"ask_password": "Contrasenya",
|
||||||
"ask_path": "Camí",
|
"backup_abstract_method": "Encara està per implementar aquest mètode de còpia de seguretat",
|
||||||
"backup_abstract_method": "Encara no s'ha implementat aquest mètode de copia de seguretat",
|
|
||||||
"backup_action_required": "S'ha d'especificar què s'ha de guardar",
|
|
||||||
"backup_app_failed": "No s'ha pogut fer la còpia de seguretat de l'aplicació \"{app:s}\"",
|
"backup_app_failed": "No s'ha pogut fer la còpia de seguretat de l'aplicació \"{app:s}\"",
|
||||||
"backup_applying_method_borg": "Enviant tots els fitxers de la còpia de seguretat al repositori borg-backup…",
|
"backup_applying_method_borg": "Enviant tots els fitxers de la còpia de seguretat al repositori borg-backup…",
|
||||||
"backup_applying_method_copy": "Còpia de tots els fitxers a la còpia de seguretat…",
|
"backup_applying_method_copy": "Còpia de tots els fitxers a la còpia de seguretat…",
|
||||||
"backup_applying_method_custom": "Crida del mètode de còpia de seguretat personalitzat \"{method:s}\"…",
|
"backup_applying_method_custom": "Crida del mètode de còpia de seguretat personalitzat \"{method:s}\"…",
|
||||||
"backup_applying_method_tar": "Creació de l'arxiu tar de la còpia de seguretat…",
|
"backup_applying_method_tar": "Creació de l'arxiu TAR de la còpia de seguretat…",
|
||||||
"backup_archive_app_not_found": "L'aplicació \"{app:s}\" no es troba dins l'arxiu de la còpia de seguretat",
|
"backup_archive_app_not_found": "No s'ha pogut trobar l'aplicació «{app:s}» dins l'arxiu de la còpia de seguretat",
|
||||||
"backup_archive_broken_link": "No s'ha pogut accedir a l'arxiu de la còpia de seguretat (enllaç invàlid cap a {path:s})",
|
"backup_archive_broken_link": "No s'ha pogut accedir a l'arxiu de la còpia de seguretat (enllaç invàlid cap a {path:s})",
|
||||||
"backup_archive_mount_failed": "No s'ha pogut carregar l'arxiu de la còpia de seguretat",
|
"backup_archive_name_exists": "Ja hi ha una còpia de seguretat amb aquest nom.",
|
||||||
"backup_archive_name_exists": "Ja hi ha una còpia de seguretat amb aquest nom",
|
|
||||||
"backup_archive_name_unknown": "Còpia de seguretat local \"{name:s}\" desconeguda",
|
"backup_archive_name_unknown": "Còpia de seguretat local \"{name:s}\" desconeguda",
|
||||||
"backup_archive_open_failed": "No s'ha pogut obrir l'arxiu de la còpia de seguretat",
|
"backup_archive_open_failed": "No s'ha pogut obrir l'arxiu de la còpia de seguretat",
|
||||||
"backup_archive_system_part_not_available": "La part \"{part:s}\" del sistema no està disponible en aquesta copia de seguretat",
|
"backup_archive_system_part_not_available": "La part «{part:s}» del sistema no està disponible en aquesta copia de seguretat",
|
||||||
"backup_archive_writing_error": "No es poden afegir arxius a l'arxiu comprimit de la còpia de seguretat",
|
"backup_archive_writing_error": "No es poden afegir els arxius «{source:s}» (anomenats en l'arxiu «{dest:s}») a l'arxiu comprimit de la còpia de seguretat «{archive:s}»",
|
||||||
"backup_ask_for_copying_if_needed": "Alguns fitxers no s'han pogut preparar per la còpia de seguretat utilitzant el mètode que evita malgastar espai del sistema temporalment. Per fer la còpia de seguretat, s'han d'utilitzar {size:s}MB temporalment. Hi esteu d'acord?",
|
"backup_ask_for_copying_if_needed": "Voleu fer la còpia de seguretat utilitzant {size:s} MB temporalment? (S'utilitza aquest mètode ja que alguns dels fitxers no s'han pogut preparar utilitzar un mètode més eficient.)",
|
||||||
"backup_borg_not_implemented": "El mètode de còpia de seguretat Borg encara no està implementat",
|
"backup_borg_not_implemented": "El mètode de còpia de seguretat Borg encara no està implementat",
|
||||||
"backup_cant_mount_uncompress_archive": "No es pot carregar en mode de lectura només el directori de l'arxiu descomprimit",
|
"backup_cant_mount_uncompress_archive": "No es pot carregar l'arxiu descomprimit com a protegit contra escriptura",
|
||||||
"backup_cleaning_failed": "No s'ha pogut netejar el directori temporal de la còpia de seguretat",
|
"backup_cleaning_failed": "No s'ha pogut netejar el directori temporal de la còpia de seguretat",
|
||||||
"backup_copying_to_organize_the_archive": "Copiant {size:s}MB per organitzar l'arxiu",
|
"backup_copying_to_organize_the_archive": "Copiant {size:s}MB per organitzar l'arxiu",
|
||||||
"backup_couldnt_bind": "No es pot lligar {src:s} amb {dest:s}.",
|
"backup_couldnt_bind": "No es pot lligar {src:s} amb {dest:s}.",
|
||||||
"backup_created": "S'ha creat la còpia de seguretat",
|
"backup_created": "S'ha creat la còpia de seguretat",
|
||||||
"backup_creating_archive": "Creant l'arxiu de la còpia de seguretat…",
|
|
||||||
"aborting": "Avortant.",
|
"aborting": "Avortant.",
|
||||||
"app_not_upgraded": "Les següents aplicacions no s'han actualitzat: {apps}",
|
"app_not_upgraded": "L'aplicació «{failed_app}» no s'ha pogut actualitzar, i com a conseqüència l'actualització de les següents aplicacions ha estat cancel·lada: {apps}",
|
||||||
"app_start_install": "instal·lant l'aplicació {app}…",
|
"app_start_install": "instal·lant l'aplicació «{app}»…",
|
||||||
"app_start_remove": "Eliminant l'aplicació {app}…",
|
"app_start_remove": "Eliminant l'aplicació «{app}»…",
|
||||||
"app_start_backup": "Recuperant els fitxers pels que s'ha de fer una còpia de seguretat per {app}…",
|
"app_start_backup": "Recuperant els fitxers pels que s'ha de fer una còpia de seguretat per «{app}»…",
|
||||||
"app_start_restore": "Recuperant l'aplicació {app}…",
|
"app_start_restore": "Recuperant l'aplicació «{app}»…",
|
||||||
"app_upgrade_several_apps": "S'actualitzaran les següents aplicacions: {apps}",
|
"app_upgrade_several_apps": "S'actualitzaran les següents aplicacions: {apps}",
|
||||||
"ask_new_domain": "Nou domini",
|
"ask_new_domain": "Nou domini",
|
||||||
"ask_new_path": "Nou camí",
|
"ask_new_path": "Nou camí",
|
||||||
"backup_actually_backuping": "S'està creant un arxiu de còpia de seguretat a partir dels fitxers recuperats…",
|
"backup_actually_backuping": "Creant un arxiu de còpia de seguretat a partir dels fitxers recuperats…",
|
||||||
"backup_creation_failed": "Ha fallat la creació de la còpia de seguretat",
|
"backup_creation_failed": "No s'ha pogut crear l'arxiu de la còpia de seguretat",
|
||||||
"backup_csv_addition_failed": "No s'han pogut afegir fitxers per a fer-ne la còpia de seguretat al fitxer CSV",
|
"backup_csv_addition_failed": "No s'han pogut afegir fitxers per a fer-ne la còpia de seguretat al fitxer CSV",
|
||||||
"backup_csv_creation_failed": "No s'ha pogut crear el fitxer CSV necessari per a futures operacions de recuperació",
|
"backup_csv_creation_failed": "No s'ha pogut crear el fitxer CSV necessari per a la restauració",
|
||||||
"backup_custom_backup_error": "El mètode de còpia de seguretat personalitzat ha fallat a l'etapa \"backup\"",
|
"backup_custom_backup_error": "El mètode de còpia de seguretat personalitzat ha fallat a l'etapa «backup»",
|
||||||
"backup_custom_mount_error": "El mètode de còpia de seguretat personalitzat ha fallat a l'etapa \"mount\"",
|
"backup_custom_mount_error": "El mètode de còpia de seguretat personalitzat ha fallat a l'etapa «mount»",
|
||||||
"backup_custom_need_mount_error": "El mètode de còpia de seguretat personalitzat ha fallat a l'etapa \"need_mount\"",
|
"backup_delete_error": "No s'ha pogut suprimir «{path:s}»",
|
||||||
"backup_delete_error": "No s'ha pogut suprimir \"{path:s}\"",
|
|
||||||
"backup_deleted": "S'ha suprimit la còpia de seguretat",
|
"backup_deleted": "S'ha suprimit la còpia de seguretat",
|
||||||
"backup_extracting_archive": "Extraient l'arxiu de la còpia de seguretat…",
|
"backup_hook_unknown": "Script de còpia de seguretat «{hook:s}» desconegut",
|
||||||
"backup_hook_unknown": "Script de còpia de seguretat \"{hook:s}\" desconegut",
|
"backup_invalid_archive": "Aquest no és un arxiu de còpia de seguretat",
|
||||||
"backup_invalid_archive": "Arxiu de còpia de seguretat no vàlid",
|
"backup_method_borg_finished": "La còpia de seguretat a Borg ha acabat",
|
||||||
"backup_method_borg_finished": "La còpia de seguretat a borg ha acabat",
|
|
||||||
"backup_method_copy_finished": "La còpia de la còpia de seguretat ha acabat",
|
"backup_method_copy_finished": "La còpia de la còpia de seguretat ha acabat",
|
||||||
"backup_method_custom_finished": "El mètode de còpia de seguretat personalitzat \"{method:s}\" ha acabat",
|
"backup_method_custom_finished": "El mètode de còpia de seguretat personalitzat \"{method:s}\" ha acabat",
|
||||||
"backup_method_tar_finished": "S'ha creat l'arxiu de còpia de seguretat tar",
|
"backup_method_tar_finished": "S'ha creat l'arxiu de còpia de seguretat TAR",
|
||||||
"backup_mount_archive_for_restore": "Preparant l'arxiu per la restauració…",
|
"backup_mount_archive_for_restore": "Preparant l'arxiu per la restauració…",
|
||||||
"good_practices_about_user_password": "Esteu a punt de definir una nova contrasenya d'usuari. La contrasenya ha de tenir un mínim de 8 caràcters ; tot i que és de bona pràctica utilitzar una contrasenya més llarga (és a dir una frase de contrasenya) i/o utilitzar diferents tipus de caràcters (majúscules, minúscules, dígits i caràcters especials).",
|
"good_practices_about_user_password": "Esteu a punt de definir una nova contrasenya d'usuari. La contrasenya ha de tenir un mínim de 8 caràcters; tot i que és de bona pràctica utilitzar una contrasenya més llarga (és a dir una frase de contrasenya) i/o utilitzar diferents tipus de caràcters (majúscules, minúscules, dígits i caràcters especials).",
|
||||||
"password_listed": "Aquesta contrasenya és una de les més utilitzades en el món. Si us plau utilitzeu-ne una més única.",
|
"password_listed": "Aquesta contrasenya és una de les més utilitzades en el món. Si us plau utilitzeu-ne una més única.",
|
||||||
"password_too_simple_1": "La contrasenya ha de tenir un mínim de 8 caràcters",
|
"password_too_simple_1": "La contrasenya ha de tenir un mínim de 8 caràcters",
|
||||||
"password_too_simple_2": "La contrasenya ha de tenir un mínim de 8 caràcters i ha de contenir dígits, majúscules i minúscules",
|
"password_too_simple_2": "La contrasenya ha de tenir un mínim de 8 caràcters i ha de contenir dígits, majúscules i minúscules",
|
||||||
|
@ -115,71 +90,58 @@
|
||||||
"password_too_simple_4": "La contrasenya ha de tenir un mínim de 12 caràcters i tenir dígits, majúscules, minúscules i caràcters especials",
|
"password_too_simple_4": "La contrasenya ha de tenir un mínim de 12 caràcters i tenir dígits, majúscules, minúscules i caràcters especials",
|
||||||
"backup_no_uncompress_archive_dir": "El directori de l'arxiu descomprimit no existeix",
|
"backup_no_uncompress_archive_dir": "El directori de l'arxiu descomprimit no existeix",
|
||||||
"backup_nothings_done": "No hi ha res a guardar",
|
"backup_nothings_done": "No hi ha res a guardar",
|
||||||
"backup_output_directory_forbidden": "Directori de sortida no permès. Les còpies de seguretat no es poden crear ni dins els directoris /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ni dins els subdirectoris /home/yunohost.backup/archives",
|
"backup_output_directory_forbidden": "Escolliu un directori de sortida different. Les còpies de seguretat no es poden crear ni dins els directoris /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ni dins els subdirectoris /home/yunohost.backup/archives",
|
||||||
"backup_output_directory_not_empty": "El directori de sortida no està buit",
|
"backup_output_directory_not_empty": "Heu d'escollir un directori de sortida buit",
|
||||||
"backup_output_directory_required": "Heu d'especificar un directori de sortida per la còpia de seguretat",
|
"backup_output_directory_required": "Heu d'especificar un directori de sortida per la còpia de seguretat",
|
||||||
"backup_output_symlink_dir_broken": "Teniu un enllaç simbòlic trencat en lloc del directori dels arxius '{path:s}'. Pot ser teniu una configuració per la còpia de seguretat específica en un altre sistema de fitxers, si és el cas segurament heu oblidat muntar o connectar el disc dur o la clau USB.",
|
"backup_output_symlink_dir_broken": "El directori del arxiu «{path:s}» es un enllaç simbòlic trencat. Pot ser heu oblidat muntar, tornar a muntar o connectar el mitja d'emmagatzematge al que apunta.",
|
||||||
"backup_php5_to_php7_migration_may_fail": "No s'ha pogut convertir l'arxiu per suportar php7, la restauració de les vostres aplicacions pot fallar (raó: {error:s})",
|
"backup_php5_to_php7_migration_may_fail": "No s'ha pogut convertir l'arxiu per suportar PHP 7, pot ser que no es puguin restaurar les vostres aplicacions PHP (raó: {error:s})",
|
||||||
"backup_running_hooks": "Executant els scripts de la còpia de seguretat…",
|
"backup_running_hooks": "Executant els scripts de la còpia de seguretat…",
|
||||||
"backup_system_part_failed": "No s'ha pogut fer la còpia de seguretat de la part \"{part:s}\" del sistema",
|
"backup_system_part_failed": "No s'ha pogut fer la còpia de seguretat de la part \"{part:s}\" del sistema",
|
||||||
"backup_unable_to_organize_files": "No s'han pogut organitzar els fitxers dins de l'arxiu amb el mètode ràpid",
|
"backup_unable_to_organize_files": "No s'ha pogut utilitzar el mètode ràpid per organitzar els fitxers dins de l'arxiu",
|
||||||
"backup_with_no_backup_script_for_app": "L'aplicació {app:s} no té un script de còpia de seguretat. Serà ignorat.",
|
"backup_with_no_backup_script_for_app": "L'aplicació «{app:s}» no té un script de còpia de seguretat. Serà ignorat.",
|
||||||
"backup_with_no_restore_script_for_app": "L'aplicació {app:s} no té un script de restauració, no podreu restaurar automàticament la còpia de seguretat d'aquesta aplicació.",
|
"backup_with_no_restore_script_for_app": "L'aplicació «{app:s}» no té un script de restauració, no podreu restaurar automàticament la còpia de seguretat d'aquesta aplicació.",
|
||||||
"certmanager_acme_not_configured_for_domain": "El certificat pel domini {domain:s} sembla que no està instal·lat correctament. Si us plau executeu primer cert-install per aquest domini.",
|
"certmanager_acme_not_configured_for_domain": "El certificat pel domini «{domain:s}» sembla que no està instal·lat correctament. Si us plau executeu primer «cert-install» per aquest domini.",
|
||||||
"certmanager_attempt_to_renew_nonLE_cert": "El certificat pel domini {domain:s} no ha estat emès per Let's Encrypt. No es pot renovar automàticament!",
|
"certmanager_attempt_to_renew_nonLE_cert": "El certificat pel domini «{domain:s}» no ha estat emès per Let's Encrypt. No es pot renovar automàticament!",
|
||||||
"certmanager_attempt_to_renew_valid_cert": "El certificat pel domini {domain:s} està a punt de caducar! (Utilitzeu --force si sabeu el que esteu fent)",
|
"certmanager_attempt_to_renew_valid_cert": "El certificat pel domini «{domain:s}» està a punt de caducar! (Utilitzeu --force si sabeu el que esteu fent)",
|
||||||
"certmanager_attempt_to_replace_valid_cert": "Esteu intentant sobreescriure un certificat correcte i vàlid pel domini {domain:s}! (Utilitzeu --force per ometre)",
|
"certmanager_attempt_to_replace_valid_cert": "Esteu intentant sobreescriure un certificat correcte i vàlid pel domini {domain:s}! (Utilitzeu --force per ometre)",
|
||||||
"certmanager_cannot_read_cert": "S'ha produït un error al intentar obrir el certificat actual pel domini {domain:s} (arxiu: {file:s}), raó: {reason:s}",
|
"certmanager_cannot_read_cert": "S'ha produït un error al intentar obrir el certificat actual pel domini {domain:s} (arxiu: {file:s}), raó: {reason:s}",
|
||||||
"certmanager_cert_install_success": "S'ha instal·lat correctament un certificat Let's Encrypt pel domini {domain:s}!",
|
"certmanager_cert_install_success": "S'ha instal·lat correctament un certificat Let's Encrypt pel domini «{domain:s}»",
|
||||||
"certmanager_cert_install_success_selfsigned": "S'ha instal·lat correctament un certificat auto-signat pel domini {domain:s}!",
|
"certmanager_cert_install_success_selfsigned": "S'ha instal·lat correctament un certificat auto-signat pel domini «{domain:s}»",
|
||||||
"certmanager_cert_renew_success": "S'ha renovat correctament el certificat Let's Encrypt pel domini {domain:s}!",
|
"certmanager_cert_renew_success": "S'ha renovat correctament el certificat Let's Encrypt pel domini «{domain:s}»",
|
||||||
"certmanager_cert_signing_failed": "No s'ha pogut firmar el nou certificat",
|
"certmanager_cert_signing_failed": "No s'ha pogut firmar el nou certificat",
|
||||||
"certmanager_certificate_fetching_or_enabling_failed": "Sembla que l'activació del nou certificat per {domain:s} ha fallat…",
|
"certmanager_certificate_fetching_or_enabling_failed": "Sembla que utilitzar el nou certificat per {domain:s} ha fallat…",
|
||||||
"certmanager_conflicting_nginx_file": "No s'ha pogut preparar el domini per al desafiament ACME: l'arxiu de configuració nginx {filepath:s} entra en conflicte i s'ha d'eliminar primer",
|
"certmanager_conflicting_nginx_file": "No s'ha pogut preparar el domini per al desafiament ACME: l'arxiu de configuració NGINX {filepath:s} entra en conflicte i s'ha d'eliminar primer",
|
||||||
"certmanager_couldnt_fetch_intermediate_cert": "S'ha exhaurit el temps d'esperar al intentar recollir el certificat intermedi des de Let's Encrypt. La instal·lació/renovació del certificat s'ha cancel·lat - torneu a intentar-ho més tard.",
|
"certmanager_couldnt_fetch_intermediate_cert": "S'ha exhaurit el temps d'esperar al intentar recollir el certificat intermedi des de Let's Encrypt. La instal·lació/renovació del certificat s'ha cancel·lat - torneu a intentar-ho més tard.",
|
||||||
"certmanager_domain_cert_not_selfsigned": "El certificat pel domini {domain:s} no és auto-signat Esteu segur de voler canviar-lo? (Utilitzeu --force per fer-ho)",
|
"certmanager_domain_cert_not_selfsigned": "El certificat pel domini {domain:s} no és auto-signat Esteu segur de voler canviar-lo? (Utilitzeu «--force» per fer-ho)",
|
||||||
"certmanager_domain_dns_ip_differs_from_public_ip": "El registre DNS \"A\" pel domini {domain:s} és diferent a l'adreça IP d'aquest servidor. Si heu modificat recentment el registre A, si us plau espereu a que es propagui (hi ha eines per verificar la propagació disponibles a internet). (Si sabeu el que esteu fent, podeu utilitzar --no-checks per desactivar aquestes comprovacions.)",
|
"certmanager_domain_dns_ip_differs_from_public_ip": "El registre DNS \"A\" pel domini «{domain:s}» és diferent a l'adreça IP d'aquest servidor. Si heu modificat recentment el registre A, si us plau espereu a que es propagui (hi ha eines per verificar la propagació disponibles a internet). (Si sabeu el que esteu fent, podeu utilitzar «--no-checks» per desactivar aquestes comprovacions.)",
|
||||||
"certmanager_domain_http_not_working": "Sembla que el domini {domain:s} no és accessible via HTTP. Si us plau verifiqueu que les configuracions DNS i nginx siguin correctes",
|
"certmanager_domain_http_not_working": "Sembla que el domini {domain:s} no és accessible via HTTP. Verifiqueu que les configuracions DNS i NGINX siguin correctes",
|
||||||
"certmanager_domain_not_resolved_locally": "El domini {domain:s} no es pot resoldre dins del vostre servidor YunoHost. Això pot passar si heu modificat recentment el registre DNS. Si és així, si us plau espereu unes hores per a que es propagui. Si el problema continua, considereu afegir {domain:s} a /etc/hosts. (Si sabeu el que esteu fent, podeu utilitzar --no-checks per desactivar aquestes comprovacions.)",
|
"certmanager_domain_unknown": "Domini desconegut «{domain:s}»",
|
||||||
"certmanager_domain_unknown": "Domini desconegut {domain:s}",
|
"certmanager_error_no_A_record": "No s'ha trobat cap registre DNS «A» per «{domain:s}». Heu de fer que el vostre nom de domini apunti cap a la vostra màquina per tal de poder instal·lar un certificat Let's Encrypt. (Si sabeu el que esteu fent, podeu utilitzar «--no-checks» per desactivar aquestes comprovacions.)",
|
||||||
"certmanager_error_no_A_record": "No s'ha trobat cap registre DNS \"A\" per {domain:s}. Heu de fer que el vostre nom de domini apunti cap a la vostra màquina per tal de poder instal·lar un certificat Let's Encrypt! (Si sabeu el que esteu fent, podeu utilitzar --no-checks per desactivar aquestes comprovacions.)",
|
|
||||||
"certmanager_hit_rate_limit": "S'han emès massa certificats recentment per aquest mateix conjunt de dominis {domain:s}. Si us plau torneu-ho a intentar més tard. Consulteu https://letsencrypt.org/docs/rate-limits/ per obtenir més detalls",
|
"certmanager_hit_rate_limit": "S'han emès massa certificats recentment per aquest mateix conjunt de dominis {domain:s}. Si us plau torneu-ho a intentar més tard. Consulteu https://letsencrypt.org/docs/rate-limits/ per obtenir més detalls",
|
||||||
"certmanager_http_check_timeout": "S'ha exhaurit el temps d'espera quan el servidor ha intentat contactar amb ell mateix via HTTP utilitzant la seva adreça IP pública (domini domain:s} amb IP {ip:s}). Pot ser degut a hairpinning o a que el talla focs/router al que està connectat el servidor estan mal configurats.",
|
"certmanager_http_check_timeout": "S'ha exhaurit el temps d'espera quan el servidor ha intentat contactar amb ell mateix via HTTP utilitzant la seva adreça IP pública (domini «{domain:s}» amb IP «{ip:s}»). Pot ser degut a hairpinning o a que el talla focs/router al que està connectat el servidor estan mal configurats.",
|
||||||
"certmanager_no_cert_file": "No s'ha pogut llegir l'arxiu del certificat pel domini {domain:s} (fitxer: {file:s})",
|
"certmanager_no_cert_file": "No s'ha pogut llegir l'arxiu del certificat pel domini {domain:s} (fitxer: {file:s})",
|
||||||
"certmanager_self_ca_conf_file_not_found": "No s'ha trobat el fitxer de configuració per l'autoritat del certificat auto-signat (fitxer: {file:s})",
|
"certmanager_self_ca_conf_file_not_found": "No s'ha trobat el fitxer de configuració per l'autoritat del certificat auto-signat (fitxer: {file:s})",
|
||||||
"certmanager_unable_to_parse_self_CA_name": "No s'ha pogut analitzar el nom de l'autoritat del certificat auto-signat (fitxer: {file:s})",
|
"certmanager_unable_to_parse_self_CA_name": "No s'ha pogut analitzar el nom de l'autoritat del certificat auto-signat (fitxer: {file:s})",
|
||||||
"confirm_app_install_warning": "Atenció: aquesta aplicació funciona però no està ben integrada amb YunoHost. Algunes característiques com la autenticació única i la còpia de seguretat/restauració poden no estar disponibles. Voleu instal·lar-la de totes maneres? [{answers:s}] ",
|
"confirm_app_install_warning": "Atenció: Aquesta aplicació funciona, però no està ben integrada amb YunoHost. Algunes característiques com la autenticació única i la còpia de seguretat/restauració poden no estar disponibles. Voleu instal·lar-la de totes maneres? [{answers:s}] ",
|
||||||
"confirm_app_install_danger": "ATENCIÓ! Aquesta aplicació encara és experimental (si no és que no funciona directament) i és probable que trenqui el sistema! No hauríeu d'instal·lar-la a no ser que sapigueu el que feu. Esteu segurs de voler córrer aquest risc? [{answers:s}] ",
|
"confirm_app_install_danger": "PERILL! Aquesta aplicació encara és experimental (si no és que no funciona directament)! No hauríeu d'instal·lar-la a no ser que sapigueu el que feu. No obtindreu CAP AJUDA si l'aplicació no funciona o trenca el sistema… Si accepteu el risc, escriviu «{answers:s}»",
|
||||||
"confirm_app_install_thirdparty": "ATENCIÓ! La instal·lació d'aplicacions de terceres parts pot comprometre la integritat i seguretat del seu sistema. Faci-ho sota la seva responsabilitat.No hauríeu d'instal·lar-ne a no ser que sapigueu el que feu. Esteu segurs de voler córrer aquest risc? [{answers:s}] ",
|
"confirm_app_install_thirdparty": "PERILL! Aquesta aplicació no es part del catàleg d'aplicacions de YunoHost. La instal·lació d'aplicacions de terceres parts pot comprometre la integritat i seguretat del seu sistema. No hauríeu d'instal·lar-ne a no ser que sapigueu el que feu. No obtindreu CAP AJUDA si l'aplicació no funciona o trenca el sistema… Si accepteu el risc, escriviu «{answers:s}»",
|
||||||
"custom_app_url_required": "Heu de especificar una URL per actualitzar la vostra aplicació personalitzada {app:s}",
|
"custom_app_url_required": "Heu de especificar una URL per actualitzar la vostra aplicació personalitzada {app:s}",
|
||||||
"custom_appslist_name_required": "Heu d'especificar un nom per la vostra llista d'aplicacions personalitzada",
|
|
||||||
"diagnosis_debian_version_error": "No s'ha pogut obtenir la versió Debian: {error}",
|
|
||||||
"diagnosis_kernel_version_error": "No s'ha pogut obtenir la versió del nucli: {error}",
|
|
||||||
"diagnosis_monitor_disk_error": "No es poden monitorar els discs: {error}",
|
|
||||||
"diagnosis_monitor_network_error": "No es pot monitorar la xarxa: {error}",
|
|
||||||
"diagnosis_monitor_system_error": "No es pot monitorar el sistema: {error}",
|
|
||||||
"diagnosis_no_apps": "No hi ha cap aplicació instal·lada",
|
|
||||||
"admin_password_too_long": "Trieu una contrasenya de menys de 127 caràcters",
|
"admin_password_too_long": "Trieu una contrasenya de menys de 127 caràcters",
|
||||||
"dpkg_is_broken": "No es pot fer això en aquest instant perquè dpkg/apt (els gestors de paquets del sistema) sembla estar mal configurat... Podeu intentar solucionar-ho connectant-vos per ssh i executant \"sudo dpkg --configure -a\".",
|
"dpkg_is_broken": "No es pot fer això en aquest instant perquè dpkg/APT (els gestors de paquets del sistema) sembla estar mal configurat… Podeu intentar solucionar-ho connectant-vos per SSH i executant «sudo dpkg --configure -a».",
|
||||||
"dnsmasq_isnt_installed": "sembla que dnsmasq no està instal·lat, executeu \"apt-get remove bind9 && apt-get install dnsmasq\"",
|
"domain_cannot_remove_main": "No es pot eliminar «{domain:s}» ja que és el domini principal, primer s'ha d'establir un nou domini principal utilitzant «yunohost domain main-domain -n <un-altre-domini>»; aquí hi ha una llista dels possibles dominis: {other_domains:s}",
|
||||||
"domain_cannot_remove_main": "No es pot eliminar el domini principal. S'ha d'establir un nou domini primer",
|
|
||||||
"domain_cert_gen_failed": "No s'ha pogut generar el certificat",
|
"domain_cert_gen_failed": "No s'ha pogut generar el certificat",
|
||||||
"domain_created": "S'ha creat el domini",
|
"domain_created": "S'ha creat el domini",
|
||||||
"domain_creation_failed": "No s'ha pogut crear el domini",
|
"domain_creation_failed": "No s'ha pogut crear el domini {domain}: {error}",
|
||||||
"domain_deleted": "S'ha eliminat el domini",
|
"domain_deleted": "S'ha eliminat el domini",
|
||||||
"domain_deletion_failed": "No s'ha pogut eliminar el domini",
|
"domain_deletion_failed": "No s'ha pogut eliminar el domini {domain}: {error}",
|
||||||
"domain_exists": "El domini ja existeix",
|
"domain_exists": "El domini ja existeix",
|
||||||
"app_action_cannot_be_ran_because_required_services_down": "Aquesta aplicació necessita serveis que estan aturats. Abans de continuar, hauríeu d'intentar arrancar de nou els serveis següents (i també investigar perquè estan aturats) : {services}",
|
"app_action_cannot_be_ran_because_required_services_down": "Aquests serveis necessaris haurien d'estar funcionant per poder executar aquesta acció: {services} Intenteu reiniciar-los per continuar (i possiblement investigar perquè estan aturats).",
|
||||||
"domain_dns_conf_is_just_a_recommendation": "Aquesta ordre mostra la configuració *recomanada*. En cap cas fa la configuració del DNS. És la vostra responsabilitat configurar la zona DNS en el vostre registrar en acord amb aquesta recomanació.",
|
"domain_dns_conf_is_just_a_recommendation": "Aquesta ordre mostra la configuració *recomanada*. En cap cas fa la configuració del DNS. És la vostra responsabilitat configurar la zona DNS en el vostre registrar en acord amb aquesta recomanació.",
|
||||||
"domain_dyndns_already_subscribed": "Ja us heu subscrit a un domini DynDNS",
|
"domain_dyndns_already_subscribed": "Ja us heu subscrit a un domini DynDNS",
|
||||||
"domain_dyndns_dynette_is_unreachable": "No s'ha pogut abastar la dynette YunoHost, o bé YunoHost no està connectat a internet correctament o bé el servidor dynette està caigut. Error: {error}",
|
|
||||||
"domain_dyndns_invalid": "Domini no vàlid per utilitzar amb DynDNS",
|
|
||||||
"domain_dyndns_root_unknown": "Domini DynDNS principal desconegut",
|
"domain_dyndns_root_unknown": "Domini DynDNS principal desconegut",
|
||||||
"domain_hostname_failed": "No s'ha pogut establir un nou nom d'amfitrió. Això podria causar problemes més tard (no és segur ... podria no passar res).",
|
"domain_hostname_failed": "No s'ha pogut establir un nou nom d'amfitrió. Això podria causar problemes més tard (podria no passar res).",
|
||||||
"domain_uninstall_app_first": "Hi ha una o més aplicacions instal·lades en aquest domini. Desinstal·leu les abans d'eliminar el domini",
|
"domain_uninstall_app_first": "Hi ha una o més aplicacions instal·lades en aquest domini. Desinstal·leu les abans d'eliminar el domini",
|
||||||
"domain_unknown": "Domini desconegut",
|
"domain_unknown": "Domini desconegut",
|
||||||
"domain_zone_exists": "El fitxer de zona DNS ja existeix",
|
|
||||||
"domain_zone_not_found": "No s'ha trobat el fitxer de zona DNS pel domini {:s}",
|
|
||||||
"domains_available": "Dominis disponibles:",
|
"domains_available": "Dominis disponibles:",
|
||||||
"done": "Fet",
|
"done": "Fet",
|
||||||
"downloading": "Descarregant…",
|
"downloading": "Descarregant…",
|
||||||
|
@ -187,68 +149,61 @@
|
||||||
"dyndns_could_not_check_available": "No s'ha pogut verificar la disponibilitat de {domain:s} a {provider:s}.",
|
"dyndns_could_not_check_available": "No s'ha pogut verificar la disponibilitat de {domain:s} a {provider:s}.",
|
||||||
"dyndns_ip_update_failed": "No s'ha pogut actualitzar l'adreça IP al DynDNS",
|
"dyndns_ip_update_failed": "No s'ha pogut actualitzar l'adreça IP al DynDNS",
|
||||||
"dyndns_ip_updated": "S'ha actualitzat l'adreça IP al DynDNS",
|
"dyndns_ip_updated": "S'ha actualitzat l'adreça IP al DynDNS",
|
||||||
"dyndns_key_generating": "S'està generant la clau DNS, això pot trigar una estona…",
|
"dyndns_key_generating": "S'està generant la clau DNS… això pot trigar una estona.",
|
||||||
"dyndns_key_not_found": "No s'ha trobat la clau DNS pel domini",
|
"dyndns_key_not_found": "No s'ha trobat la clau DNS pel domini",
|
||||||
"dyndns_no_domain_registered": "No hi ha cap domini registrat amb DynDNS",
|
"dyndns_no_domain_registered": "No hi ha cap domini registrat amb DynDNS",
|
||||||
"dyndns_registered": "S'ha registrat el domini DynDNS",
|
"dyndns_registered": "S'ha registrat el domini DynDNS",
|
||||||
"dyndns_registration_failed": "No s'ha pogut registrar el domini DynDNS: {error:s}",
|
"dyndns_registration_failed": "No s'ha pogut registrar el domini DynDNS: {error:s}",
|
||||||
"dyndns_domain_not_provided": "El proveïdor {provider:s} no pot oferir el domini {domain:s}.",
|
"dyndns_domain_not_provided": "El proveïdor de DynDNS {provider:s} no pot oferir el domini {domain:s}.",
|
||||||
"dyndns_unavailable": "El domini {domain:s} no està disponible.",
|
"dyndns_unavailable": "El domini {domain:s} no està disponible.",
|
||||||
"executing_command": "Execució de l'ordre « {command:s} »…",
|
"executing_command": "Execució de l'ordre « {command:s} »…",
|
||||||
"executing_script": "Execució de l'script « {script:s} »…",
|
"executing_script": "Execució de l'script « {script:s} »…",
|
||||||
"extracting": "Extracció en curs…",
|
"extracting": "Extracció en curs…",
|
||||||
"dyndns_cron_installed": "S'ha instal·lat la tasca cron pel DynDNS",
|
"dyndns_cron_installed": "S'ha creat la tasca cron pel DynDNS",
|
||||||
"dyndns_cron_remove_failed": "No s'ha pogut eliminar la tasca cron per a DynDNS: {error}",
|
"dyndns_cron_remove_failed": "No s'ha pogut eliminar la tasca cron per a DynDNS: {error}",
|
||||||
"dyndns_cron_removed": "S'ha eliminat la tasca cron pel DynDNS",
|
"dyndns_cron_removed": "S'ha eliminat la tasca cron pel DynDNS",
|
||||||
"experimental_feature": "Atenció: aquesta funcionalitat és experimental i no es considera estable, no s'ha d'utilitzar a excepció de saber el que esteu fent.",
|
"experimental_feature": "Atenció: Aquesta funcionalitat és experimental i no es considera estable, no s'ha d'utilitzar a excepció de saber el que esteu fent.",
|
||||||
"field_invalid": "Camp incorrecte « {:s} »",
|
"field_invalid": "Camp incorrecte « {:s} »",
|
||||||
"file_does_not_exist": "El camí {path:s} no existeix.",
|
"file_does_not_exist": "El camí {path:s} no existeix.",
|
||||||
"firewall_reload_failed": "No s'ha pogut tornar a carregar el tallafoc",
|
"firewall_reload_failed": "No s'ha pogut tornar a carregar el tallafocs",
|
||||||
"firewall_reloaded": "S'ha tornat a carregar el tallafoc",
|
"firewall_reloaded": "S'ha tornat a carregar el tallafocs",
|
||||||
"firewall_rules_cmd_failed": "No s'han pogut aplicar algunes regles del tallafoc. Mireu el registre per a més informació.",
|
"firewall_rules_cmd_failed": "No s'han pogut aplicar algunes regles del tallafocs. Més informació en el registre.",
|
||||||
"format_datetime_short": "%d/%m/%Y %H:%M",
|
"global_settings_bad_choice_for_enum": "Opció pel paràmetre {setting:s} incorrecta, s'ha rebut «{choice:s}», però les opcions disponibles són: {available_choices:s}",
|
||||||
"global_settings_bad_choice_for_enum": "Opció pel paràmetre {setting:s} incorrecta, s'ha rebut «{choice:s}» però les opcions disponibles són: {available_choices:s}",
|
|
||||||
"global_settings_bad_type_for_setting": "El tipus del paràmetre {setting:s} és incorrecte. S'ha rebut {received_type:s}, però s'esperava {expected_type:s}",
|
"global_settings_bad_type_for_setting": "El tipus del paràmetre {setting:s} és incorrecte. S'ha rebut {received_type:s}, però s'esperava {expected_type:s}",
|
||||||
"global_settings_cant_open_settings": "No s'ha pogut obrir el fitxer de configuració, raó: {reason:s}",
|
"global_settings_cant_open_settings": "No s'ha pogut obrir el fitxer de configuració, raó: {reason:s}",
|
||||||
"global_settings_cant_serialize_settings": "No s'ha pogut serialitzar les dades de configuració, raó: {reason:s}",
|
"global_settings_cant_serialize_settings": "No s'ha pogut serialitzar les dades de configuració, raó: {reason:s}",
|
||||||
"global_settings_cant_write_settings": "No s'ha pogut escriure el fitxer de configuració, raó: {reason:s}",
|
"global_settings_cant_write_settings": "No s'ha pogut escriure el fitxer de configuració, raó: {reason:s}",
|
||||||
"global_settings_key_doesnt_exists": "La clau « {settings_key:s} » no existeix en la configuració global, podeu veure totes les claus disponibles executant « yunohost settings list »",
|
"global_settings_key_doesnt_exists": "La clau « {settings_key:s} » no existeix en la configuració global, podeu veure totes les claus disponibles executant « yunohost settings list »",
|
||||||
"global_settings_reset_success": "Èxit. S'ha fet una còpia de seguretat de la configuració anterior a {path:s}",
|
"global_settings_reset_success": "S'ha fet una còpia de seguretat de la configuració anterior a {path:s}",
|
||||||
"global_settings_setting_example_bool": "Exemple d'opció booleana",
|
"global_settings_setting_example_bool": "Exemple d'opció booleana",
|
||||||
"global_settings_setting_example_enum": "Exemple d'opció de tipus enumeració",
|
"global_settings_setting_example_enum": "Exemple d'opció de tipus enumeració",
|
||||||
"global_settings_setting_example_int": "Exemple d'opció de tipus enter",
|
"global_settings_setting_example_int": "Exemple d'opció de tipus enter",
|
||||||
"global_settings_setting_example_string": "Exemple d'opció de tipus cadena",
|
"global_settings_setting_example_string": "Exemple d'opció de tipus cadena",
|
||||||
"global_settings_setting_security_nginx_compatibility": "Solució de compromís entre compatibilitat i seguretat pel servidor web nginx. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)",
|
"global_settings_setting_security_nginx_compatibility": "Solució de compromís entre compatibilitat i seguretat pel servidor web NGINX. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)",
|
||||||
"global_settings_setting_security_password_admin_strength": "Robustesa de la contrasenya d'administrador",
|
"global_settings_setting_security_password_admin_strength": "Robustesa de la contrasenya d'administrador",
|
||||||
"global_settings_setting_security_password_user_strength": "Robustesa de la contrasenya de l'usuari",
|
"global_settings_setting_security_password_user_strength": "Robustesa de la contrasenya de l'usuari",
|
||||||
"global_settings_setting_security_ssh_compatibility": "Solució de compromís entre compatibilitat i seguretat pel servidor SSH. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)",
|
"global_settings_setting_security_ssh_compatibility": "Solució de compromís entre compatibilitat i seguretat pel servidor SSH. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)",
|
||||||
"global_settings_unknown_setting_from_settings_file": "Clau de configuració desconeguda: «{setting_key:s}», refusant-la i guardant-la a /etc/yunohost/settings-unknown.json",
|
"global_settings_unknown_setting_from_settings_file": "Clau de configuració desconeguda: «{setting_key:s}», refusada i guardada a /etc/yunohost/settings-unknown.json",
|
||||||
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Permetre la clau d'hoste DSA (obsolet) per la configuració del servei SSH",
|
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Permetre la clau d'hoste DSA (obsolet) per la configuració del servei SSH",
|
||||||
"global_settings_unknown_type": "Situació inesperada, la configuració {setting:s} sembla tenir el tipus {unknown_type:s} però no és un tipus reconegut pel sistema.",
|
"global_settings_unknown_type": "Situació inesperada, la configuració {setting:s} sembla tenir el tipus {unknown_type:s} però no és un tipus reconegut pel sistema.",
|
||||||
"good_practices_about_admin_password": "Esteu a punt de definir una nova contrasenya d'administrador. La contrasenya ha de tenir un mínim de 8 caràcters ; tot i que és de bona pràctica utilitzar una contrasenya més llarga (és a dir una frase de contrasenya) i/o utilitzar diferents tipus de caràcters (majúscules, minúscules, dígits i caràcters especials).",
|
"good_practices_about_admin_password": "Esteu a punt de definir una nova contrasenya d'administrador. La contrasenya ha de tenir un mínim de 8 caràcters; tot i que és de bona pràctica utilitzar una contrasenya més llarga (és a dir una frase de contrasenya) i/o utilitzar diferents tipus de caràcters (majúscules, minúscules, dígits i caràcters especials).",
|
||||||
"hook_exec_failed": "No s'ha pogut executar l'script: {path:s}",
|
"hook_exec_failed": "No s'ha pogut executar el script: {path:s}",
|
||||||
"hook_exec_not_terminated": "L'execució de l'script « {path:s} » no s'ha acabat correctament",
|
"hook_exec_not_terminated": "El script no s'ha acabat correctament: {path:s}",
|
||||||
"hook_json_return_error": "No s'ha pogut llegir el retorn de l'script {path:s}. Error: {msg:s}. Contingut en brut: {raw_content}",
|
"hook_json_return_error": "No s'ha pogut llegir el retorn del script {path:s}. Error: {msg:s}. Contingut en brut: {raw_content}",
|
||||||
"hook_list_by_invalid": "Propietat per llistar les accions invàlida",
|
"hook_list_by_invalid": "Aquesta propietat no es pot utilitzar per llistar els hooks",
|
||||||
"hook_name_unknown": "Nom de script « {name:s} » desconegut",
|
"hook_name_unknown": "Nom de script « {name:s} » desconegut",
|
||||||
"installation_complete": "Instal·lació completada",
|
"installation_complete": "Instal·lació completada",
|
||||||
"installation_failed": "Ha fallat la instal·lació",
|
"installation_failed": "Ha fallat alguna cosa amb la instal·lació",
|
||||||
"invalid_url_format": "Format d'URL invàlid",
|
|
||||||
"ip6tables_unavailable": "No podeu modificar les ip6tables aquí. O bé sou en un contenidor o bé el vostre nucli no és compatible amb aquesta opció",
|
"ip6tables_unavailable": "No podeu modificar les ip6tables aquí. O bé sou en un contenidor o bé el vostre nucli no és compatible amb aquesta opció",
|
||||||
"iptables_unavailable": "No podeu modificar les iptables aquí. O bé sou en un contenidor o bé el vostre nucli no és compatible amb aquesta opció",
|
"iptables_unavailable": "No podeu modificar les iptables aquí. O bé sou en un contenidor o bé el vostre nucli no és compatible amb aquesta opció",
|
||||||
"log_corrupted_md_file": "El fitxer de metadades yaml associat amb els registres està malmès: « {md_file} »\nError: {error}",
|
"log_corrupted_md_file": "El fitxer de metadades YAML associat amb els registres està malmès: « {md_file} »\nError: {error}",
|
||||||
"log_category_404": "La categoria de registres « {category} » no existeix",
|
"log_category_404": "La categoria de registres « {category} » no existeix",
|
||||||
"log_link_to_log": "El registre complet d'aquesta operació: «<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\">{desc}</a>»",
|
"log_link_to_log": "El registre complet d'aquesta operació: «<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\">{desc}</a>»",
|
||||||
"log_help_to_get_log": "Per veure el registre de l'operació « {desc} », utilitzeu l'ordre « yunohost log display {name} »",
|
"log_help_to_get_log": "Per veure el registre de l'operació « {desc} », utilitzeu l'ordre « yunohost log display {name} »",
|
||||||
"log_link_to_failed_log": "L'operació « {dec} » ha fallat! Per obtenir ajuda, <a href=\"#/tools/logs/{name}\">proveïu el registre complete de l'operació clicant aquí</a>",
|
"log_link_to_failed_log": "No s'ha pogut completar l'operació « {desc} ». Per obtenir ajuda, <a href=\"#/tools/logs/{name}\">proveïu el registre complete de l'operació clicant aquí</a>",
|
||||||
"log_help_to_get_failed_log": "L'operació « {dec} » ha fallat! Per obtenir ajuda, compartiu el registre complete de l'operació utilitzant l'ordre « yunohost log display {name} --share »",
|
"log_help_to_get_failed_log": "No s'ha pogut completar l'operació « {desc} ». Per obtenir ajuda, compartiu el registre complete de l'operació utilitzant l'ordre « yunohost log display {name} --share »",
|
||||||
"log_does_exists": "No hi ha cap registre per l'operació amb el nom« {log} », utilitzeu « yunohost log list » per veure tots els registre d'operació disponibles",
|
"log_does_exists": "No hi ha cap registre per l'operació amb el nom« {log} », utilitzeu « yunohost log list » per veure tots els registre d'operació disponibles",
|
||||||
"log_operation_unit_unclosed_properly": "L'operació no s'ha tancat de forma correcta",
|
"log_operation_unit_unclosed_properly": "L'operació no s'ha tancat de forma correcta",
|
||||||
"log_app_addaccess": "Afegir accés a « {} »",
|
|
||||||
"log_app_removeaccess": "Suprimeix accés a « {} »",
|
|
||||||
"log_app_clearaccess": "Suprimeix tots els accessos a « {} »",
|
|
||||||
"log_app_fetchlist": "Afegeix una llista d'aplicacions",
|
|
||||||
"log_app_removelist": "Elimina una llista d'aplicacions",
|
|
||||||
"log_app_change_url": "Canvia l'URL de l'aplicació « {} »",
|
"log_app_change_url": "Canvia l'URL de l'aplicació « {} »",
|
||||||
"log_app_install": "Instal·la l'aplicació « {} »",
|
"log_app_install": "Instal·la l'aplicació « {} »",
|
||||||
"log_app_remove": "Elimina l'aplicació « {} »",
|
"log_app_remove": "Elimina l'aplicació « {} »",
|
||||||
|
@ -263,139 +218,99 @@
|
||||||
"log_domain_remove": "Elimina el domini « {} » de la configuració del sistema",
|
"log_domain_remove": "Elimina el domini « {} » de la configuració del sistema",
|
||||||
"log_dyndns_subscribe": "Subscriure's a un subdomini YunoHost « {} »",
|
"log_dyndns_subscribe": "Subscriure's a un subdomini YunoHost « {} »",
|
||||||
"log_dyndns_update": "Actualitza la IP associada al subdomini YunoHost « {} »",
|
"log_dyndns_update": "Actualitza la IP associada al subdomini YunoHost « {} »",
|
||||||
"log_letsencrypt_cert_install": "Instal·la el certificat Let's Encrypt al domini « {} »",
|
"log_letsencrypt_cert_install": "Instal·la un certificat Let's Encrypt al domini « {} »",
|
||||||
"log_selfsigned_cert_install": "Instal·la el certificat autosignat al domini « {} »",
|
"log_selfsigned_cert_install": "Instal·la el certificat autosignat al domini « {} »",
|
||||||
"log_letsencrypt_cert_renew": "Renova el certificat Let's Encrypt de « {} »",
|
"log_letsencrypt_cert_renew": "Renova el certificat Let's Encrypt de « {} »",
|
||||||
"log_service_enable": "Activa el servei « {} »",
|
|
||||||
"log_regen_conf": "Regenera la configuració del sistema « {} »",
|
"log_regen_conf": "Regenera la configuració del sistema « {} »",
|
||||||
"log_user_create": "Afegeix l'usuari « {} »",
|
"log_user_create": "Afegeix l'usuari « {} »",
|
||||||
"log_user_delete": "Elimina l'usuari « {} »",
|
"log_user_delete": "Elimina l'usuari « {} »",
|
||||||
"log_user_update": "Actualitza la informació de l'usuari « {} »",
|
"log_user_update": "Actualitza la informació de l'usuari « {} »",
|
||||||
"log_tools_maindomain": "Fes de « {} » el domini principal",
|
"log_domain_main_domain": "Fes de « {} » el domini principal",
|
||||||
"log_tools_migrations_migrate_forward": "Migrar",
|
"log_tools_migrations_migrate_forward": "Executa les migracions",
|
||||||
"log_tools_migrations_migrate_backward": "Migrar endarrera",
|
|
||||||
"log_tools_postinstall": "Fer la post instal·lació del servidor YunoHost",
|
"log_tools_postinstall": "Fer la post instal·lació del servidor YunoHost",
|
||||||
"log_tools_upgrade": "Actualitza els paquets del sistema",
|
"log_tools_upgrade": "Actualitza els paquets del sistema",
|
||||||
"log_tools_shutdown": "Apaga el servidor",
|
"log_tools_shutdown": "Apaga el servidor",
|
||||||
"log_tools_reboot": "Reinicia el servidor",
|
"log_tools_reboot": "Reinicia el servidor",
|
||||||
"already_up_to_date": "No hi ha res a fer! Tot està al dia!",
|
"already_up_to_date": "No hi ha res a fer. Tot està actualitzat.",
|
||||||
"dpkg_lock_not_available": "No es pot utilitzar aquesta comanda en aquest moment ja que sembla que un altre programa està utilitzant el lock de dpkg (el gestor de paquets del sistema)",
|
"dpkg_lock_not_available": "No es pot utilitzar aquesta comanda en aquest moment ja que sembla que un altre programa està utilitzant el lock de dpkg (el gestor de paquets del sistema)",
|
||||||
"global_settings_setting_security_postfix_compatibility": "Solució de compromís entre compatibilitat i seguretat pel servidor Postfix. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)",
|
"global_settings_setting_security_postfix_compatibility": "Solució de compromís entre compatibilitat i seguretat pel servidor Postfix. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)",
|
||||||
"ldap_init_failed_to_create_admin": "La inicialització de LDAP no ha pogut crear l'usuari admin",
|
"ldap_init_failed_to_create_admin": "La inicialització de LDAP no ha pogut crear l'usuari admin",
|
||||||
"ldap_initialized": "S'ha iniciat LDAP",
|
"ldap_initialized": "S'ha iniciat LDAP",
|
||||||
"license_undefined": "indefinit",
|
"mail_alias_remove_failed": "No s'han pogut eliminar els àlies del correu «{mail:s}»",
|
||||||
"mail_alias_remove_failed": "No s'han pogut eliminar els alias del correu «{mail:s}»",
|
"mail_domain_unknown": "El domini «{domain:s}» de l'adreça de correu no és vàlid. Utilitzeu un domini administrat per aquest servidor.",
|
||||||
"mail_domain_unknown": "Domini d'adreça de correu «{domain:s}» desconegut",
|
|
||||||
"mail_forward_remove_failed": "No s'han pogut eliminar el reenviament de correu «{mail:s}»",
|
"mail_forward_remove_failed": "No s'han pogut eliminar el reenviament de correu «{mail:s}»",
|
||||||
"mailbox_used_space_dovecot_down": "S'ha d'engegar el servei de correu Dovecot per poder obtenir l'espai utilitzat per la bústia de correu",
|
"mailbox_used_space_dovecot_down": "S'ha d'engegar el servei de correu Dovecot, per poder obtenir l'espai utilitzat per la bústia de correu",
|
||||||
"mail_unavailable": "Aquesta adreça de correu esta reservada i ha de ser atribuïda automàticament el primer usuari",
|
"mail_unavailable": "Aquesta adreça de correu està reservada i ha de ser atribuïda automàticament el primer usuari",
|
||||||
"maindomain_change_failed": "No s'ha pogut canviar el domini principal",
|
"main_domain_change_failed": "No s'ha pogut canviar el domini principal",
|
||||||
"maindomain_changed": "S'ha canviat el domini principal",
|
"main_domain_changed": "S'ha canviat el domini principal",
|
||||||
"migrate_tsig_end": "La migració cap a hmac-sha512 s'ha acabat",
|
"migrate_tsig_end": "La migració cap a HMAC-SHA-512 s'ha acabat",
|
||||||
"migrate_tsig_failed": "Ha fallat la migració del domini dyndns {domain} cap a hmac-sha512, anul·lant les modificacions. Error: {error_code} - {error}",
|
"migrate_tsig_failed": "Ha fallat la migració del domini DynDNS «{domain}» cap a HMAC-SHA-512, anul·lant les modificacions. Error: {error_code}, {error}",
|
||||||
"migrate_tsig_start": "L'algoritme de generació de claus no es prou segur per a la signatura TSIG del domini «{domain}», començant la migració cap a un de més segur hmac-sha512",
|
"migrate_tsig_start": "L'algoritme de generació de claus no es prou segur per a la signatura TSIG del domini «{domain}», començant la migració cap a un de més segur HMAC-SHA-512",
|
||||||
"migrate_tsig_wait": "Esperar 3 minuts per a que el servidor dyndns tingui en compte la nova clau…",
|
"migrate_tsig_wait": "Esperant tres minuts per a que el servidor DynDNS tingui en compte la nova clau…",
|
||||||
"migrate_tsig_wait_2": "2 minuts…",
|
"migrate_tsig_wait_2": "2 minuts…",
|
||||||
"migrate_tsig_wait_3": "1 minut…",
|
"migrate_tsig_wait_3": "1 minut…",
|
||||||
"migrate_tsig_wait_4": "30 segons…",
|
"migrate_tsig_wait_4": "30 segons…",
|
||||||
"migrate_tsig_not_needed": "Sembla que no s'utilitza cap domini dyndns, no és necessari fer cap migració!",
|
"migrate_tsig_not_needed": "Sembla que no s'utilitza cap domini DynDNS, no és necessari fer cap migració.",
|
||||||
"migration_description_0001_change_cert_group_to_sslcert": "Canvia els permisos del grup dels certificats de «metronome» a «ssl-cert»",
|
"migration_description_0001_change_cert_group_to_sslcert": "Canvia els permisos del grup dels certificats de «metronome» a «ssl-cert»",
|
||||||
"migration_description_0002_migrate_to_tsig_sha256": "Millora la seguretat de dyndns TSIG utilitzant SHA512 en lloc de MD5",
|
"migration_description_0002_migrate_to_tsig_sha256": "Millora la seguretat de DynDNS TSIG utilitzant SHA-512 en lloc de MD5",
|
||||||
"migration_description_0003_migrate_to_stretch": "Actualització del sistema a Debian Stretch i YunoHost 3.0",
|
"migration_description_0003_migrate_to_stretch": "Actualització del sistema a Debian Stretch i YunoHost 3.0",
|
||||||
"migration_description_0004_php5_to_php7_pools": "Tornar a configurar els pools PHP per utilitzar PHP 7 en lloc de PHP 5",
|
"migration_description_0004_php5_to_php7_pools": "Tornar a configurar els pools PHP per utilitzar PHP 7 en lloc de PHP 5",
|
||||||
"migration_description_0005_postgresql_9p4_to_9p6": "Migració de les bases de dades de postgresql 9.4 a 9.6",
|
"migration_description_0005_postgresql_9p4_to_9p6": "Migració de les bases de dades de PostgreSQL 9.4 a 9.6",
|
||||||
"migration_description_0006_sync_admin_and_root_passwords": "Sincronitzar les contrasenyes admin i root",
|
"migration_description_0006_sync_admin_and_root_passwords": "Sincronitzar les contrasenyes admin i root",
|
||||||
"migration_description_0007_ssh_conf_managed_by_yunohost_step1": "La configuració SSH serà gestionada per YunoHost (pas 1, automàtic)",
|
"migration_description_0007_ssh_conf_managed_by_yunohost_step1": "La configuració SSH serà gestionada per YunoHost (pas 1, automàtic)",
|
||||||
"migration_description_0008_ssh_conf_managed_by_yunohost_step2": "La configuració SSH serà gestionada per YunoHost (pas 2, manual)",
|
"migration_description_0008_ssh_conf_managed_by_yunohost_step2": "La configuració SSH serà gestionada per YunoHost (pas 2, manual)",
|
||||||
"migration_description_0009_decouple_regenconf_from_services": "Desvincula el mecanisme regen-conf dels serveis",
|
"migration_description_0009_decouple_regenconf_from_services": "Desvincula el mecanisme regen-conf dels serveis",
|
||||||
"migration_description_0010_migrate_to_apps_json": "Elimina la appslists (desfasat) i utilitza la nova llista unificada «apps.json» en el seu lloc",
|
"migration_description_0010_migrate_to_apps_json": "Elimina els catàlegs d'aplicacions obsolets i utilitza la nova llista unificada «apps.json» en el seu lloc (obsolet, substituït per la migració 13)",
|
||||||
"migration_0003_backward_impossible": "La migració Stretch no és reversible.",
|
|
||||||
"migration_0003_start": "Ha començat la migració a Stretch. Els registres estaran disponibles a {logfile}.",
|
"migration_0003_start": "Ha començat la migració a Stretch. Els registres estaran disponibles a {logfile}.",
|
||||||
"migration_0003_patching_sources_list": "Modificant el fitxer sources.lists…",
|
"migration_0003_patching_sources_list": "Modificant el fitxer sources.lists…",
|
||||||
"migration_0003_main_upgrade": "Començant l'actualització principal…",
|
"migration_0003_main_upgrade": "Començant l'actualització principal…",
|
||||||
"migration_0003_fail2ban_upgrade": "Començant l'actualització de fail2ban…",
|
"migration_0003_fail2ban_upgrade": "Començant l'actualització de Fail2Ban…",
|
||||||
"migration_0003_restoring_origin_nginx_conf": "El fitxer /etc/nginx/nginx.conf ha estat editat. La migració el tornarà al seu estat original... El fitxer anterior estarà disponible com a {backup_dest}.",
|
"migration_0003_restoring_origin_nginx_conf": "El fitxer /etc/nginx/nginx.conf ha estat editat. La migració el tornarà al seu estat original... El fitxer anterior estarà disponible com a {backup_dest}.",
|
||||||
"migration_0003_yunohost_upgrade": "Començant l'actualització del paquet yunohost... La migració acabarà, però l'actualització actual es farà just després. Després de completar aquesta operació, pot ser que us hagueu de tornar a connectar a la web d'administració.",
|
"migration_0003_yunohost_upgrade": "Començant l'actualització del paquet YunoHost... La migració acabarà, però l'actualització actual es farà just després. Després de completar aquesta operació, pot ser que us hagueu de tornar a connectar a la web d'administració.",
|
||||||
"migration_0003_not_jessie": "La distribució Debian actual no és Jessie!",
|
"migration_0003_not_jessie": "La distribució Debian actual no és Jessie!",
|
||||||
"migration_0003_system_not_fully_up_to_date": "El vostre sistema no està completament actualitzat. S'ha de fer una actualització normal abans de fer la migració a Stretch.",
|
"migration_0003_system_not_fully_up_to_date": "El vostre sistema no està completament actualitzat. S'ha de fer una actualització normal abans de fer la migració a Stretch.",
|
||||||
"migration_0003_still_on_jessie_after_main_upgrade": "Hi ha hagut un problema durant l'actualització principal: el sistema encara està amb Jessie!? Per investigar el problema, mireu el registres a {log}:s…",
|
"migration_0003_still_on_jessie_after_main_upgrade": "Hi ha hagut un problema durant l'actualització principal: El sistema encara està amb Jessie? Per investigar el problema, mireu el registres a {log}:s…",
|
||||||
"migration_0003_general_warning": "Tingueu en compte que la migració és una operació delicada. Tot i que l'equip de YunoHost a fet els possibles per revisar-la i provar-la, la migració pot provocar errors en parts del sistema o aplicacions.\n\nPer tant, recomanem:\n - Fer una còpia de seguretat de les dades o aplicacions importants. Més informació a https://yunohost.org/backup;\n - Sigueu pacient un cop llençada la migració: en funció de la connexió a internet i el maquinari, pot trigar fins a unes hores per actualitzar-ho tot.\n\nD'altra banda, el port per SMTP, utilitzat per clients de correu externs (com Thunderbird o K9-Mail) ha canviat de 465 (SSL/TLS) a 587 (STARTTLS). L'antic port 465 serà tancat automàticament i el nou port 587 serà obert en el tallafocs. Tots els usuaris *hauran* d'adaptar la configuració dels clients de correu en acord amb aquests canvis!",
|
"migration_0003_general_warning": "Tingueu en compte que la migració és una operació delicada. L'equip de YunoHost a fet els possibles per revisar-la i provar-la, però la migració pot provocar errors en parts del sistema o aplicacions.\n\nPer tant, es recomana:\n - Fer una còpia de seguretat de les dades o aplicacions importants. Més informació a https://yunohost.org/backup;\n - Sigueu pacient un cop llençada la migració: en funció de la connexió a internet i el maquinari, pot trigar fins a unes hores per actualitzar-ho tot.\n\nD'altra banda, el port per SMTP, utilitzat per clients de correu externs (com Thunderbird o K9-Mail) ha canviat de 465 (SSL/TLS) a 587 (STARTTLS). L'antic port (465) serà tancat automàticament, i el nou port (587) serà obert en el tallafocs. Tots els usuaris *hauran* d'adaptar la configuració dels clients de correu en acord amb aquests canvis.",
|
||||||
"migration_0003_problematic_apps_warning": "Tingueu en compte que s'han detectat les aplicacions, possiblement, problemàtiques següents. Sembla que aquestes no s'han instal·lat des d'una applist o que no estan marcades com a «working». Per conseqüent, no podem garantir que segueixin funcionant després de l'actualització: {problematic_apps}",
|
"migration_0003_problematic_apps_warning": "Tingueu en compte que s'han detectat les aplicacions, possiblement, problemàtiques següents. Sembla que aquestes no s'han instal·lat des d'un catàleg d'aplicacions, o que no estan marcades com a «working». Per conseqüent, no podem garantir que segueixin funcionant després de l'actualització: {problematic_apps}",
|
||||||
"migration_0003_modified_files": "Tingueu en compte que s'han detectat els següents fitxers que han estat modificats manualment i podrien sobreescriure's al final de l'actualització: {manually_modified_files}",
|
"migration_0003_modified_files": "Tingueu en compte que s'han detectat els següents fitxers que han estat modificats manualment i podrien sobreescriure's al final de l'actualització: {manually_modified_files}",
|
||||||
"migration_0005_postgresql_94_not_installed": "Postgresql no està instal·lat en el sistema. No hi ha res per fer!",
|
"migration_0005_postgresql_94_not_installed": "PostgreSQL no està instal·lat en el sistema. No hi ha res per fer.",
|
||||||
"migration_0005_postgresql_96_not_installed": "S'ha trobat Postgresql 9.4 instal·lat, però no Postgresql 9.6!? Alguna cosa estranya a passat en el sistema :( …",
|
"migration_0005_postgresql_96_not_installed": "PostgreSQL 9.4 està instal·lat, però no PostgreSQL 9.6? Alguna cosa estranya a passat en el sistema :( …",
|
||||||
"migration_0005_not_enough_space": "No hi ha prou espai disponible en {path} per fer la migració en aquest moment :(.",
|
"migration_0005_not_enough_space": "Creu espai disponible en {path} per executar la migració.",
|
||||||
"migration_0006_disclaimer": "YunoHost esperar que les contrasenyes admin i root estiguin sincronitzades. Fent aquesta migració, la contrasenya root serà reemplaçada per la contrasenya admin.",
|
"migration_0006_disclaimer": "YunoHost esperar que les contrasenyes de admin i root estiguin sincronitzades. Aquesta migració canvia la contrasenya root per la contrasenya admin.",
|
||||||
"migration_0007_cancelled": "YunoHost no ha pogut millorar la gestió de la configuració SSH.",
|
"migration_0007_cancelled": "No s'ha pogut millorar la gestió de la configuració SSH.",
|
||||||
"migration_0007_cannot_restart": "No es pot reiniciar SSH després d'haver intentat cancel·lar la migració numero 6.",
|
"migration_0007_cannot_restart": "No es pot reiniciar SSH després d'haver intentat cancel·lar la migració numero 6.",
|
||||||
"migration_0008_general_disclaimer": "Per millorar la seguretat del servidor, es recomana que sigui YunoHost qui gestioni la configuració SSH. La configuració SSH actual és diferent a la configuració recomanada. Si deixeu que YunoHost ho reconfiguri, la manera de connectar-se al servidor mitjançant SSH canviarà de la següent manera:",
|
"migration_0008_general_disclaimer": "Per millorar la seguretat del servidor, es recomana que sigui YunoHost qui gestioni la configuració SSH. La configuració SSH actual és diferent a la configuració recomanada. Si deixeu que YunoHost ho reconfiguri, la manera de connectar-se al servidor mitjançant SSH canviarà de la següent manera:",
|
||||||
"migration_0008_port": " - la connexió es farà utilitzant el port 22 en lloc del port SSH personalitzat actual. Es pot reconfigurar;",
|
"migration_0008_port": "• La connexió es farà utilitzant el port 22 en lloc del port SSH personalitzat actual. Es pot reconfigurar;",
|
||||||
"migration_0008_root": " - no es podrà connectar com a root a través de SSH. S'haurà d'utilitzar l'usuari admin per fer-ho;",
|
"migration_0008_root": "• No es podrà connectar com a root a través de SSH. S'haurà d'utilitzar l'usuari admin per fer-ho;",
|
||||||
"migration_0008_dsa": " - es desactivarà la clau DSA. Per tant, es podria haver d'invalidar un missatge esgarrifós del client SSH, i tornar a verificar l'empremta digital del servidor;",
|
"migration_0008_dsa": "• Es desactivarà la clau DSA. Per tant, es podria haver d'invalidar un missatge esgarrifós del client SSH, i tornar a verificar l'empremta digital del servidor;",
|
||||||
"migration_0008_warning": "Si heu entès els avisos i accepteu que YunoHost sobreescrigui la configuració actual, comenceu la migració. Sinó, podeu saltar-vos la migració, tot i que no està recomanat.",
|
"migration_0008_warning": "Si heu entès els avisos i voleu que YunoHost sobreescrigui la configuració actual, comenceu la migració. Sinó, podeu saltar-vos la migració, tot i que no està recomanat.",
|
||||||
"migration_0008_no_warning": "No s'han detectat riscs importants per sobreescriure la configuració SSH, però no es pot estar del tot segur ;)! Si accepteu que YunoHost sobreescrigui la configuració actual, comenceu la migració. Sinó, podeu saltar-vos la migració, tot i que no està recomanat.",
|
"migration_0008_no_warning": "Hauria de ser segur sobreescriure la configuració SSH, però no es pot estar del tot segur! Executetu la migració per sobreescriure-la. Sinó, podeu saltar-vos la migració, tot i que no està recomanat.",
|
||||||
"migration_0009_not_needed": "Sembla que ja s'ha fet aquesta migració? Ometent.",
|
"migration_0009_not_needed": "Sembla que ja s'ha fet aquesta migració… (?) Ometent.",
|
||||||
"migrations_backward": "Migració cap enrere.",
|
"migrations_cant_reach_migration_file": "No s'ha pogut accedir als fitxers de migració al camí «%s»",
|
||||||
"migrations_bad_value_for_target": "Nombre invàlid pel paràmetre target, els nombres de migració disponibles són 0 o {}",
|
"migrations_list_conflict_pending_done": "No es pot utilitzar «--previous» i «--done» al mateix temps.",
|
||||||
"migrations_cant_reach_migration_file": "No s'ha pogut accedir als fitxers de migració al camí %s",
|
"migrations_loading_migration": "Carregant la migració {id}…",
|
||||||
"migrations_current_target": "La migració objectiu és {}",
|
"migrations_migration_has_failed": "La migració {id} ha fallat, cancel·lant. Error: {exception}",
|
||||||
"migrations_error_failed_to_load_migration": "ERROR: no s'ha pogut carregar la migració {number} {name}",
|
|
||||||
"migrations_forward": "Migració endavant",
|
|
||||||
"migrations_list_conflict_pending_done": "No es pot utilitzar --previous i --done al mateix temps.",
|
|
||||||
"migrations_loading_migration": "Carregant la migració {number} {name}…",
|
|
||||||
"migrations_migration_has_failed": "La migració {number} {name} ha fallat amb l'excepció {exception}, cancel·lant",
|
|
||||||
"migrations_no_migrations_to_run": "No hi ha cap migració a fer",
|
"migrations_no_migrations_to_run": "No hi ha cap migració a fer",
|
||||||
"migrations_show_currently_running_migration": "Fent la migració {number} {name}…",
|
"migrations_skip_migration": "Saltant migració {id}…",
|
||||||
"migrations_show_last_migration": "L'última migració feta és {}",
|
"migrations_to_be_ran_manually": "La migració {id} s'ha de fer manualment. Aneu a Eines → Migracions a la interfície admin, o executeu «yunohost tools migrations migrate».",
|
||||||
"migrations_skip_migration": "Saltant migració {number} {name}…",
|
"migrations_need_to_accept_disclaimer": "Per fer la migració {id}, heu d'acceptar aquesta clàusula de no responsabilitat:\n---\n{disclaimer}\n---\nSi accepteu fer la migració, torneu a executar l'ordre amb l'opció «--accept-disclaimer».",
|
||||||
"migrations_success": "S'ha completat la migració {number} {name} amb èxit!",
|
|
||||||
"migrations_to_be_ran_manually": "La migració {number} {name} s'ha de fer manualment. Aneu a Eines > Migracions a la interfície admin, o executeu «yunohost tools migrations migrate».",
|
|
||||||
"migrations_need_to_accept_disclaimer": "Per fer la migració {number} {name}, heu d'acceptar aquesta clàusula de no responsabilitat:\n---\n{disclaimer}\n---\nSi accepteu fer la migració, torneu a executar l'ordre amb l'opció --accept-disclaimer.",
|
|
||||||
"monitor_disabled": "El monitoratge del servidor ha estat desactivat",
|
|
||||||
"monitor_enabled": "El monitoratge del servidor ha estat activat",
|
|
||||||
"monitor_glances_con_failed": "No s'ha pogut connectar al servidor Glances",
|
|
||||||
"monitor_not_enabled": "El monitoratge del servidor no està activat",
|
|
||||||
"monitor_period_invalid": "Període de temps invàlid",
|
|
||||||
"monitor_stats_file_not_found": "No s'ha pogut trobar el fitxer d'estadístiques",
|
|
||||||
"monitor_stats_no_update": "No hi ha dades de monitoratge per actualitzar",
|
|
||||||
"monitor_stats_period_unavailable": "No s'han trobat estadístiques per aquest període",
|
|
||||||
"mountpoint_unknown": "Punt de muntatge desconegut",
|
|
||||||
"mysql_db_creation_failed": "No s'ha pogut crear la base de dades MySQL",
|
|
||||||
"mysql_db_init_failed": "No s'ha pogut inicialitzar la base de dades MySQL",
|
|
||||||
"mysql_db_initialized": "S'ha inicialitzat la base de dades MySQL",
|
|
||||||
"network_check_mx_ko": "El registre DNS MX no està configurat",
|
|
||||||
"network_check_smtp_ko": "El tràfic de correu sortint (SMTP port 25) sembla que està bloquejat per la xarxa",
|
|
||||||
"network_check_smtp_ok": "El tràfic de correu sortint (SMTP port 25) no està bloquejat",
|
|
||||||
"new_domain_required": "S'ha d'especificar un nou domini principal",
|
|
||||||
"no_appslist_found": "No s'ha trobat cap llista d'aplicacions",
|
|
||||||
"no_internet_connection": "El servidor no està connectat a Internet",
|
"no_internet_connection": "El servidor no està connectat a Internet",
|
||||||
"no_ipv6_connectivity": "La connectivitat IPv6 no està disponible",
|
|
||||||
"no_restore_script": "No hi ha cap script de restauració per l'aplicació «{app:s}»",
|
|
||||||
"not_enough_disk_space": "No hi ha prou espai en «{path:s}»",
|
"not_enough_disk_space": "No hi ha prou espai en «{path:s}»",
|
||||||
"package_not_installed": "El paquet «{pkgname}» no està instal·lat",
|
|
||||||
"package_unexpected_error": "Hi ha hagut un error inesperat processant el paquet «{pkgname}»",
|
|
||||||
"package_unknown": "Paquet desconegut «{pkgname}»",
|
"package_unknown": "Paquet desconegut «{pkgname}»",
|
||||||
"packages_upgrade_critical_later": "Els paquets crítics ({packages:s}) seran actualitzats més tard",
|
|
||||||
"packages_upgrade_failed": "No s'han pogut actualitzar tots els paquets",
|
"packages_upgrade_failed": "No s'han pogut actualitzar tots els paquets",
|
||||||
"path_removal_failed": "No s'ha pogut eliminar el camí {:s}",
|
|
||||||
"pattern_backup_archive_name": "Ha de ser un nom d'arxiu vàlid amb un màxim de 30 caràcters, compost per caràcters alfanumèrics i -_. exclusivament",
|
"pattern_backup_archive_name": "Ha de ser un nom d'arxiu vàlid amb un màxim de 30 caràcters, compost per caràcters alfanumèrics i -_. exclusivament",
|
||||||
"pattern_domain": "Ha de ser un nom de domini vàlid (ex.: el-meu-domini.cat)",
|
"pattern_domain": "Ha de ser un nom de domini vàlid (ex.: el-meu-domini.cat)",
|
||||||
"pattern_email": "Ha de ser una adreça de correu vàlida (ex.: algu@domini.cat)",
|
"pattern_email": "Ha de ser una adreça de correu vàlida (ex.: algu@domini.cat)",
|
||||||
"pattern_firstname": "Ha de ser un nom vàlid",
|
"pattern_firstname": "Ha de ser un nom vàlid",
|
||||||
"pattern_lastname": "Ha de ser un cognom vàlid",
|
"pattern_lastname": "Ha de ser un cognom vàlid",
|
||||||
"pattern_listname": "Ha d'estar compost per caràcters alfanumèrics i guió baix exclusivament",
|
"pattern_mailbox_quota": "Ha de ser una mida amb el sufix b/k/M/G/T o 0 per no tenir quota",
|
||||||
"pattern_mailbox_quota": "Ha de ser una mida amb el sufix b/k/M/G/T o 0 per desactivar la quota",
|
|
||||||
"pattern_password": "Ha de tenir un mínim de 3 caràcters",
|
"pattern_password": "Ha de tenir un mínim de 3 caràcters",
|
||||||
"pattern_port": "Ha de ser un número de port vàlid (i.e. 0-65535)",
|
|
||||||
"pattern_port_or_range": "Ha de ser un número de port vàlid (i.e. 0-65535) o un interval de ports (ex. 100:200)",
|
"pattern_port_or_range": "Ha de ser un número de port vàlid (i.e. 0-65535) o un interval de ports (ex. 100:200)",
|
||||||
"pattern_positive_number": "Ha de ser un nombre positiu",
|
"pattern_positive_number": "Ha de ser un nombre positiu",
|
||||||
"pattern_username": "Ha d'estar compost per caràcters alfanumèrics en minúscula i guió baix exclusivament",
|
"pattern_username": "Ha d'estar compost per caràcters alfanumèrics en minúscula i guió baix exclusivament",
|
||||||
"pattern_password_app": "Les contrasenyes no haurien de tenir els següents caràcters: {forbidden_chars}",
|
"pattern_password_app": "Les contrasenyes no poden de tenir els següents caràcters: {forbidden_chars}",
|
||||||
"port_already_closed": "El port {port:d} ja està tancat per les connexions {ip_version:s}",
|
"port_already_closed": "El port {port:d} ja està tancat per les connexions {ip_version:s}",
|
||||||
"port_already_opened": "El port {port:d} ja està obert per les connexions {ip_version:s}",
|
"port_already_opened": "El port {port:d} ja està obert per les connexions {ip_version:s}",
|
||||||
"port_available": "El port {port:d} està disponible",
|
|
||||||
"port_unavailable": "El port {port:d} no està disponible",
|
|
||||||
"recommend_to_add_first_user": "La post instal·lació s'ha acabat, però YunoHost necessita com a mínim un usuari per funcionar correctament, hauríeu d'afegir un usuari executant «yunohost user create $username» o amb la interfície d'administració.",
|
|
||||||
"regenconf_file_backed_up": "S'ha guardat una còpia de seguretat del fitxer de configuració «{conf}» a «{backup}»",
|
"regenconf_file_backed_up": "S'ha guardat una còpia de seguretat del fitxer de configuració «{conf}» a «{backup}»",
|
||||||
"regenconf_file_copy_failed": "No s'ha pogut copiar el nou fitxer de configuració «{new}» a «{conf}»",
|
"regenconf_file_copy_failed": "No s'ha pogut copiar el nou fitxer de configuració «{new}» a «{conf}»",
|
||||||
"regenconf_file_kept_back": "S'espera que el fitxer de configuració «{conf}» sigui suprimit per regen-conf (categoria {category}) però s'ha mantingut.",
|
"regenconf_file_kept_back": "S'espera que el fitxer de configuració «{conf}» sigui suprimit per regen-conf (categoria {category}) però s'ha mantingut.",
|
||||||
|
@ -406,26 +321,24 @@
|
||||||
"regenconf_file_updated": "El fitxer de configuració «{conf}» ha estat actualitzat",
|
"regenconf_file_updated": "El fitxer de configuració «{conf}» ha estat actualitzat",
|
||||||
"regenconf_now_managed_by_yunohost": "El fitxer de configuració «{conf}» serà gestionat per YunoHost a partir d'ara (categoria {category}).",
|
"regenconf_now_managed_by_yunohost": "El fitxer de configuració «{conf}» serà gestionat per YunoHost a partir d'ara (categoria {category}).",
|
||||||
"regenconf_up_to_date": "La configuració ja està al dia per la categoria «{category}»",
|
"regenconf_up_to_date": "La configuració ja està al dia per la categoria «{category}»",
|
||||||
"regenconf_updated": "La configuració ha estat actualitzada per la categoria «{category}»",
|
"regenconf_updated": "S'ha actualitzat la configuració per la categoria «{category}»",
|
||||||
"regenconf_would_be_updated": "La configuració hagués estat actualitzada per la categoria «{category}»",
|
"regenconf_would_be_updated": "La configuració hagués estat actualitzada per la categoria «{category}»",
|
||||||
"regenconf_dry_pending_applying": "Verificació de la configuració pendent que s'hauria d'haver aplicat per la categoria «{category}»…",
|
"regenconf_dry_pending_applying": "Verificació de la configuració pendent que s'hauria d'haver aplicat per la categoria «{category}»…",
|
||||||
"regenconf_failed": "No s'ha pogut regenerar la configuració per la/les categoria/es : {categories}",
|
"regenconf_failed": "No s'ha pogut regenerar la configuració per la/les categoria/es : {categories}",
|
||||||
"regenconf_pending_applying": "Aplicació de la configuració pendent per la categoria «{category}»…",
|
"regenconf_pending_applying": "Aplicació de la configuració pendent per la categoria «{category}»…",
|
||||||
"restore_action_required": "S'ha d'especificar quelcom a restaurar",
|
"restore_already_installed_app": "Una aplicació amb la ID «{app:s}» ja està instal·lada",
|
||||||
"restore_already_installed_app": "Ja hi ha una aplicació instal·lada amb l'id «{app:s}»",
|
|
||||||
"restore_app_failed": "No s'ha pogut restaurar l'aplicació «{app:s}»",
|
"restore_app_failed": "No s'ha pogut restaurar l'aplicació «{app:s}»",
|
||||||
"restore_cleaning_failed": "No s'ha pogut netejar el directori temporal de restauració",
|
"restore_cleaning_failed": "No s'ha pogut netejar el directori temporal de restauració",
|
||||||
"restore_complete": "Restauració completada",
|
"restore_complete": "Restauració completada",
|
||||||
"restore_confirm_yunohost_installed": "Esteu segur de voler restaurar un sistema ja instal·lat? [{answers:s}]",
|
"restore_confirm_yunohost_installed": "Esteu segur de voler restaurar un sistema ja instal·lat? [{answers:s}]",
|
||||||
"restore_extracting": "Extracció dels fitxers necessaris de l'arxiu…",
|
"restore_extracting": "Extracció dels fitxers necessaris de l'arxiu…",
|
||||||
"restore_failed": "No s'ha pogut restaurar el sistema",
|
"restore_failed": "No s'ha pogut restaurar el sistema",
|
||||||
"restore_hook_unavailable": "L'script de restauració «{part:s}» no està disponible en el sistema i tampoc és en l'arxiu",
|
"restore_hook_unavailable": "El script de restauració «{part:s}» no està disponible en el sistema i tampoc és en l'arxiu",
|
||||||
"restore_may_be_not_enough_disk_space": "Sembla que no hi ha prou espai disponible en el disc (espai lliure: {free_space:d} B, espai necessari: {needed_space:d} B, marge de seguretat: {margin:d} B)",
|
"restore_may_be_not_enough_disk_space": "Sembla que no hi ha prou espai disponible en el sistema (lliure: {free_space:d} B, espai necessari: {needed_space:d} B, marge de seguretat: {margin:d} B)",
|
||||||
"restore_mounting_archive": "Muntatge de l'arxiu a «{path:s}»",
|
"restore_not_enough_disk_space": "No hi ha prou espai disponible (espai: {free_space:d} B, espai necessari: {needed_space:d} B, marge de seguretat: {margin:d} B)",
|
||||||
"restore_not_enough_disk_space": "No hi ha prou espai disponible en el disc (espai lliure: {free_space:d} B, espai necessari: {needed_space:d} B, marge de seguretat: {margin:d} B)",
|
|
||||||
"restore_nothings_done": "No s'ha restaurat res",
|
"restore_nothings_done": "No s'ha restaurat res",
|
||||||
"restore_removing_tmp_dir_failed": "No s'ha pogut eliminar un directori temporal antic",
|
"restore_removing_tmp_dir_failed": "No s'ha pogut eliminar un directori temporal antic",
|
||||||
"restore_running_app_script": "Execució de l'script de restauració de l'aplicació «{app:s}»…",
|
"restore_running_app_script": "Restaurant l'aplicació «{app:s}»…",
|
||||||
"restore_running_hooks": "Execució dels hooks de restauració…",
|
"restore_running_hooks": "Execució dels hooks de restauració…",
|
||||||
"restore_system_part_failed": "No s'ha pogut restaurar la part «{part:s}» del sistema",
|
"restore_system_part_failed": "No s'ha pogut restaurar la part «{part:s}» del sistema",
|
||||||
"root_password_desynchronized": "S'ha canviat la contrasenya d'administració, però YunoHost no ha pogut propagar-ho cap a la contrasenya root!",
|
"root_password_desynchronized": "S'ha canviat la contrasenya d'administració, però YunoHost no ha pogut propagar-ho cap a la contrasenya root!",
|
||||||
|
@ -436,32 +349,29 @@
|
||||||
"server_reboot_confirm": "Es reiniciarà el servidor immediatament, n'esteu segur? [{answers:s}]",
|
"server_reboot_confirm": "Es reiniciarà el servidor immediatament, n'esteu segur? [{answers:s}]",
|
||||||
"service_add_failed": "No s'ha pogut afegir el servei «{service:s}»",
|
"service_add_failed": "No s'ha pogut afegir el servei «{service:s}»",
|
||||||
"service_added": "S'ha afegit el servei «{service:s}»",
|
"service_added": "S'ha afegit el servei «{service:s}»",
|
||||||
"service_already_started": "Ja s'ha iniciat el servei «{service:s}»",
|
"service_already_started": "El servei «{service:s}» ja està funcionant",
|
||||||
"service_already_stopped": "Ja s'ha aturat el servei «{service:s}»",
|
"service_already_stopped": "Ja s'ha aturat el servei «{service:s}»",
|
||||||
"service_cmd_exec_failed": "No s'ha pogut executar l'ordre «{command:s}»",
|
"service_cmd_exec_failed": "No s'ha pogut executar l'ordre «{command:s}»",
|
||||||
"service_description_avahi-daemon": "permet accedir al servidor via yunohost.local en la xarxa local",
|
"service_description_avahi-daemon": "Permet accedir al servidor via «yunohost.local» en la xarxa local",
|
||||||
"service_description_dnsmasq": "gestiona la resolució del nom de domini (DNS)",
|
"service_description_dnsmasq": "Gestiona la resolució del nom de domini (DNS)",
|
||||||
"service_description_dovecot": "permet als clients de correu accedir/recuperar correus (via IMAP i POP3)",
|
"service_description_dovecot": "Permet als clients de correu accedir/recuperar correus (via IMAP i POP3)",
|
||||||
"service_description_fail2ban": "protegeix contra els atacs de força bruta i a altres atacs provinents d'Internet",
|
"service_description_fail2ban": "Protegeix contra els atacs de força bruta i a altres atacs provinents d'Internet",
|
||||||
"service_description_glances": "monitora la informació del sistema en el servidor",
|
"service_description_metronome": "Gestiona els comptes de missatgeria instantània XMPP",
|
||||||
"service_description_metronome": "gestiona els comptes de missatgeria instantània XMPP",
|
"service_description_mysql": "Guarda les dades de les aplicacions (base de dades SQL)",
|
||||||
"service_description_mysql": "guarda les dades de les aplicacions (base de dades SQL)",
|
"service_description_nginx": "Serveix o permet l'accés a totes les pàgines web allotjades en el servidor",
|
||||||
"service_description_nginx": "serveix o permet l'accés a totes les pàgines web allotjades en el servidor",
|
"service_description_nslcd": "Gestiona les connexions shell dels usuaris YunoHost",
|
||||||
"service_description_nslcd": "gestiona les connexions shell dels usuaris YunoHost",
|
"service_description_php7.0-fpm": "Executa les aplicacions escrites en PHP amb NGINX",
|
||||||
"service_description_php7.0-fpm": "executa les aplicacions escrites en PHP amb nginx",
|
"service_description_postfix": "Utilitzat per enviar i rebre correus",
|
||||||
"service_description_postfix": "utilitzat per enviar i rebre correus",
|
"service_description_redis-server": "Una base de dades especialitzada per l'accés ràpid a dades, files d'espera i comunicació entre programes",
|
||||||
"service_description_redis-server": "una base de dades especialitzada per l'accés ràpid a dades, files d'espera i comunicació entre programes",
|
"service_description_rspamd": "Filtra el correu brossa, i altres funcionalitats relacionades amb el correu",
|
||||||
"service_description_rmilter": "verifica diferents paràmetres en els correus",
|
"service_description_slapd": "Guarda el usuaris, dominis i informació relacionada",
|
||||||
"service_description_rspamd": "filtra el correu brossa, i altres funcionalitats relacionades al correu",
|
"service_description_ssh": "Permet la connexió remota al servidor via terminal (protocol SSH)",
|
||||||
"service_description_slapd": "guarda el usuaris, dominis i informació relacionada",
|
"service_description_yunohost-api": "Gestiona les interaccions entre la interfície web de YunoHost i el sistema",
|
||||||
"service_description_ssh": "permet la connexió remota al servidor via terminal (protocol SSH)",
|
"service_description_yunohost-firewall": "Gestiona els ports de connexió oberts i tancats als serveis",
|
||||||
"service_description_yunohost-api": "gestiona les interaccions entre la interfície web de YunoHost i el sistema",
|
"service_disable_failed": "No s'han pogut fer que el servei «{service:s}» no comenci a l'arrancada.\n\nRegistres recents: {logs:s}",
|
||||||
"service_description_yunohost-firewall": "gestiona els ports de connexió oberts i tancats als serveis",
|
"service_disabled": "El servei «{service:s}» ja no començarà al arrancar el sistema.",
|
||||||
"service_disable_failed": "No s'han pogut deshabilitar el servei «{service:s}»\n\nRegistres recents: {logs:s}",
|
"service_enable_failed": "No s'ha pogut fer que el servei «{service:s}» comenci automàticament a l'arrancada.\n\nRegistres recents: {logs:s}",
|
||||||
"service_disabled": "S'ha deshabilitat el servei {service:s}",
|
"service_enabled": "El servei «{service:s}» començarà automàticament durant l'arrancada del sistema.",
|
||||||
"service_enable_failed": "No s'ha pogut activar el servei «{service:s}»\n\nRegistres recents: {log:s}",
|
|
||||||
"service_enabled": "S'ha activat el servei {service:s}",
|
|
||||||
"service_no_log": "No hi ha cap registre pel servei «{service:s}»",
|
|
||||||
"service_regen_conf_is_deprecated": "«yunohost service regen-conf» està desfasat! Utilitzeu «yunohost tools regen-conf» en el seu lloc.",
|
"service_regen_conf_is_deprecated": "«yunohost service regen-conf» està desfasat! Utilitzeu «yunohost tools regen-conf» en el seu lloc.",
|
||||||
"service_remove_failed": "No s'ha pogut eliminar el servei «{service:s}»",
|
"service_remove_failed": "No s'ha pogut eliminar el servei «{service:s}»",
|
||||||
"service_removed": "S'ha eliminat el servei «{service:s}»",
|
"service_removed": "S'ha eliminat el servei «{service:s}»",
|
||||||
|
@ -473,114 +383,218 @@
|
||||||
"service_reloaded_or_restarted": "S'ha tornat a carregar o s'ha reiniciat el servei «{service:s}»",
|
"service_reloaded_or_restarted": "S'ha tornat a carregar o s'ha reiniciat el servei «{service:s}»",
|
||||||
"service_start_failed": "No s'ha pogut iniciar el servei «{service:s}»\n\nRegistres recents: {logs:s}",
|
"service_start_failed": "No s'ha pogut iniciar el servei «{service:s}»\n\nRegistres recents: {logs:s}",
|
||||||
"service_started": "S'ha iniciat el servei «{service:s}»",
|
"service_started": "S'ha iniciat el servei «{service:s}»",
|
||||||
"service_status_failed": "No s'ha pogut determinar l'estat del servei «{service:s}»",
|
|
||||||
"service_stop_failed": "No s'ha pogut aturar el servei «{service:s}»\n\nRegistres recents: {logs:s}",
|
"service_stop_failed": "No s'ha pogut aturar el servei «{service:s}»\n\nRegistres recents: {logs:s}",
|
||||||
"service_stopped": "S'ha aturat el servei «{service:s}»",
|
"service_stopped": "S'ha aturat el servei «{service:s}»",
|
||||||
"service_unknown": "Servei «{service:s}» desconegut",
|
"service_unknown": "Servei «{service:s}» desconegut",
|
||||||
"ssowat_conf_generated": "S'ha generat la configuració SSOwat",
|
"ssowat_conf_generated": "S'ha generat la configuració SSOwat",
|
||||||
"ssowat_conf_updated": "S'ha actualitzat la configuració SSOwat",
|
"ssowat_conf_updated": "S'ha actualitzat la configuració SSOwat",
|
||||||
"ssowat_persistent_conf_read_error": "Error en llegir la configuració persistent de SSOwat: {error:s}. Modifiqueu el fitxer /etc/ssowat/conf.json.persistent per arreglar la sintaxi JSON",
|
|
||||||
"ssowat_persistent_conf_write_error": "Error guardant la configuració persistent de SSOwat: {error:s}. Modifiqueu el fitxer /etc/ssowat/conf.json.persistent per arreglar la sintaxi JSON",
|
|
||||||
"system_upgraded": "S'ha actualitzat el sistema",
|
"system_upgraded": "S'ha actualitzat el sistema",
|
||||||
"system_username_exists": "El nom d'usuari ja existeix en els usuaris de sistema",
|
"system_username_exists": "El nom d'usuari ja existeix en la llista d'usuaris de sistema",
|
||||||
"this_action_broke_dpkg": "Aquesta acció a trencat dpkg/apt (els gestors de paquets del sistema)… Podeu intentar resoldre el problema connectant-vos amb SSH i executant «sudo dpkg --configure -a».",
|
"this_action_broke_dpkg": "Aquesta acció a trencat dpkg/APT (els gestors de paquets del sistema)… Podeu intentar resoldre el problema connectant-vos amb SSH i executant «sudo dpkg --configure -a».",
|
||||||
"tools_upgrade_at_least_one": "Especifiqueu --apps O --system",
|
"tools_upgrade_at_least_one": "Especifiqueu «--apps», o «--system»",
|
||||||
"tools_upgrade_cant_both": "No es poden actualitzar tant el sistema com les aplicacions al mateix temps",
|
"tools_upgrade_cant_both": "No es poden actualitzar tant el sistema com les aplicacions al mateix temps",
|
||||||
"tools_upgrade_cant_hold_critical_packages": "No es poden mantenir els paquets crítics…",
|
"tools_upgrade_cant_hold_critical_packages": "No es poden mantenir els paquets crítics…",
|
||||||
"tools_upgrade_cant_unhold_critical_packages": "No es poden deixar de mantenir els paquets crítics…",
|
"tools_upgrade_cant_unhold_critical_packages": "No es poden deixar de mantenir els paquets crítics…",
|
||||||
"tools_upgrade_regular_packages": "Actualitzant els paquets «normals» (no relacionats amb YunoHost)…",
|
"tools_upgrade_regular_packages": "Actualitzant els paquets «normals» (no relacionats amb YunoHost)…",
|
||||||
"tools_upgrade_regular_packages_failed": "No s'han pogut actualitzar els paquets següents: {packages_list}",
|
"tools_upgrade_regular_packages_failed": "No s'han pogut actualitzar els paquets següents: {packages_list}",
|
||||||
"tools_upgrade_special_packages": "Actualitzant els paquets «especials» (relacionats amb YunoHost)…",
|
"tools_upgrade_special_packages": "Actualitzant els paquets «especials» (relacionats amb YunoHost)…",
|
||||||
"tools_upgrade_special_packages_explanation": "Aquesta acció s'acabarà, però l'actualització especial continuarà en segon pla. No comenceu cap altra acció al servidor en els pròxims ~10 minuts (depèn de la velocitat del maquinari). Un cop acabat, pot ser que us hagueu de tornar a connectar a la interfície d'administració. Els registres de l'actualització estaran disponibles a Eines > Registres (a la interfície d'administració) o amb «yunohost log list» (a la línia d'ordres).",
|
"tools_upgrade_special_packages_explanation": "Aquesta actualització especial continuarà en segon pla. No comenceu cap altra acció al servidor en els pròxims ~10 minuts (depèn de la velocitat del maquinari). Després d'això, pot ser que us hagueu de tornar a connectar a la interfície d'administració. Els registres de l'actualització estaran disponibles a Eines → Registres (a la interfície d'administració) o utilitzant «yunohost log list» (des de la línia d'ordres).",
|
||||||
"tools_upgrade_special_packages_completed": "Actualització dels paquets YunoHost acabada!\nPremeu [Enter] per tornar a la línia d'ordres",
|
"tools_upgrade_special_packages_completed": "Actualització dels paquets YunoHost acabada.\nPremeu [Enter] per tornar a la línia d'ordres",
|
||||||
"unbackup_app": "L'aplicació «{app:s}» no serà guardada",
|
"unbackup_app": "L'aplicació «{app:s}» no serà guardada",
|
||||||
"unexpected_error": "Hi ha hagut un error inesperat: {error}",
|
"unexpected_error": "Hi ha hagut un error inesperat: {error}",
|
||||||
"unit_unknown": "Unitat desconeguda «{unit:s}»",
|
|
||||||
"unlimit": "Sense quota",
|
"unlimit": "Sense quota",
|
||||||
"unrestore_app": "L'aplicació «{app:s} no serà restaurada",
|
"unrestore_app": "L'aplicació «{app:s} no serà restaurada",
|
||||||
"update_apt_cache_failed": "No s'ha pogut actualitzar la memòria cau d'APT (el gestor de paquets de Debian). Aquí teniu les línies de sources.list que poden ajudar-vos a identificar les línies problemàtiques:\n{sourceslist}",
|
"update_apt_cache_failed": "No s'ha pogut actualitzar la memòria cau d'APT (el gestor de paquets de Debian). Aquí teniu les línies de sources.list, que poden ajudar-vos a identificar les línies problemàtiques:\n{sourceslist}",
|
||||||
"update_apt_cache_warning": "Hi ha hagut errors al actualitzar la memòria cau d'APT (el gestor de paquets de Debian). Aquí teniu les línies de sources.list que poden ajudar-vos a identificar les línies problemàtiques:\n{sourceslist}",
|
"update_apt_cache_warning": "Hi ha hagut errors al actualitzar la memòria cau d'APT (el gestor de paquets de Debian). Aquí teniu les línies de sources.list que poden ajudar-vos a identificar les línies problemàtiques:\n{sourceslist}",
|
||||||
"updating_apt_cache": "Obtenció de les actualitzacions disponibles per als paquets del sistema…",
|
"updating_apt_cache": "Obtenció de les actualitzacions disponibles per als paquets del sistema…",
|
||||||
"updating_app_lists": "Obtenció de les actualitzacions disponibles per a les aplicacions…",
|
|
||||||
"upgrade_complete": "Actualització acabada",
|
"upgrade_complete": "Actualització acabada",
|
||||||
"upgrading_packages": "Actualitzant els paquets…",
|
"upgrading_packages": "Actualitzant els paquets…",
|
||||||
"upnp_dev_not_found": "No s'ha trobat cap dispositiu UPnP",
|
"upnp_dev_not_found": "No s'ha trobat cap dispositiu UPnP",
|
||||||
"upnp_disabled": "S'ha desactivat UPnP",
|
"upnp_disabled": "S'ha desactivat UPnP",
|
||||||
"upnp_enabled": "S'ha activat UPnP",
|
"upnp_enabled": "S'ha activat UPnP",
|
||||||
"upnp_port_open_failed": "No s'han pogut obrir els ports UPnP",
|
"upnp_port_open_failed": "No s'ha pogut obrir el port UPnP",
|
||||||
"user_created": "S'ha creat l'usuari",
|
"user_created": "S'ha creat l'usuari",
|
||||||
"user_creation_failed": "No s'ha pogut crear l'usuari",
|
"user_creation_failed": "No s'ha pogut crear l'usuari {user}: {error}",
|
||||||
"user_deleted": "S'ha suprimit l'usuari",
|
"user_deleted": "S'ha suprimit l'usuari",
|
||||||
"user_deletion_failed": "No s'ha pogut suprimir l'usuari",
|
"user_deletion_failed": "No s'ha pogut suprimir l'usuari {user}: {error}",
|
||||||
"user_home_creation_failed": "No s'ha pogut crear la carpeta personal («home») de l'usuari",
|
"user_home_creation_failed": "No s'ha pogut crear la carpeta personal «home» per l'usuari",
|
||||||
"user_info_failed": "No s'ha pogut obtenir la informació de l'usuari",
|
|
||||||
"user_unknown": "Usuari desconegut: {user:s}",
|
"user_unknown": "Usuari desconegut: {user:s}",
|
||||||
"user_update_failed": "No s'ha pogut actualitzar l'usuari",
|
"user_update_failed": "No s'ha pogut actualitzar l'usuari {user}: {error}",
|
||||||
"user_updated": "S'ha actualitzat l'usuari",
|
"user_updated": "S'ha canviat la informació de l'usuari",
|
||||||
"users_available": "Usuaris disponibles:",
|
"users_available": "Usuaris disponibles:",
|
||||||
"yunohost_already_installed": "YunoHost ja està instal·lat",
|
"yunohost_already_installed": "YunoHost ja està instal·lat",
|
||||||
"yunohost_ca_creation_failed": "No s'ha pogut crear l'autoritat de certificació",
|
"yunohost_ca_creation_failed": "No s'ha pogut crear l'autoritat de certificació",
|
||||||
"yunohost_ca_creation_success": "S'ha creat l'autoritat de certificació local.",
|
"yunohost_ca_creation_success": "S'ha creat l'autoritat de certificació local.",
|
||||||
"yunohost_configured": "S'ha configurat YunoHost",
|
"yunohost_configured": "YunoHost està configurat",
|
||||||
"yunohost_installing": "Instal·lació de YunoHost…",
|
"yunohost_installing": "Instal·lació de YunoHost…",
|
||||||
"yunohost_not_installed": "YunoHost no està instal·lat o no està instal·lat correctament. Executeu «yunohost tools postinstall»",
|
"yunohost_not_installed": "YunoHost no està instal·lat correctament. Executeu «yunohost tools postinstall»",
|
||||||
"apps_permission_not_found": "No s'ha trobat cap permís per les aplicacions instal·lades",
|
|
||||||
"apps_permission_restoration_failed": "Ha fallat el permís «{permission:s}» per la restauració de l'aplicació {app:s}",
|
|
||||||
"backup_permission": "Permís de còpia de seguretat per l'aplicació {app:s}",
|
"backup_permission": "Permís de còpia de seguretat per l'aplicació {app:s}",
|
||||||
"edit_group_not_allowed": "No teniu autorització per modificar el grup {group:s}",
|
|
||||||
"edit_permission_with_group_all_users_not_allowed": "No podeu modificar els permisos del grup «all_users», s'ha d'utlilitzar «yunohost user permission clear APP» o «yunohost user permission add APP -u USER».",
|
|
||||||
"error_when_removing_sftpuser_group": "Error intentant eliminar el gruo sftpusers",
|
|
||||||
"group_already_allowed": "El grup «{group:s}» ja té el permís «{permission:s}» activat per l'aplicació «{app:s}»",
|
|
||||||
"group_already_disallowed": "El grup «{group:s}» ja té els permisos «{permission:s}» desactivats per l'aplicació «{app:s}»",
|
|
||||||
"group_name_already_exist": "El grup {name:s} ja existeix",
|
|
||||||
"group_created": "S'ha creat el grup «{group}»",
|
"group_created": "S'ha creat el grup «{group}»",
|
||||||
"group_creation_failed": "No s'ha pogut crear el grup «{group}»",
|
"group_creation_failed": "No s'ha pogut crear el grup «{group}»: {error}",
|
||||||
"group_deleted": "S'ha eliminat el grup «{group}»",
|
"group_deleted": "S'ha eliminat el grup «{group}»",
|
||||||
"group_deletion_failed": "No s'ha pogut eliminar el grup «{group}»",
|
"group_deletion_failed": "No s'ha pogut eliminar el grup «{group}»: {error}",
|
||||||
"group_deletion_not_allowed": "El grup {group:s} no es pot eliminar manualment.",
|
|
||||||
"group_info_failed": "Ha fallat la informació del grup",
|
|
||||||
"group_unknown": "Grup {group:s} desconegut",
|
"group_unknown": "Grup {group:s} desconegut",
|
||||||
"group_updated": "S'ha actualitzat el grup «{group}»",
|
"group_updated": "S'ha actualitzat el grup «{group}»",
|
||||||
"group_update_failed": "No s'ha pogut actualitzat el grup «{group}»",
|
"group_update_failed": "No s'ha pogut actualitzat el grup «{group}»: {error}",
|
||||||
"log_permission_add": "Afegir el permís «{}» per l'aplicació «{}»",
|
|
||||||
"log_permission_remove": "Suprimir el permís «{}»",
|
|
||||||
"log_permission_update": "Actualitzar el permís «{}» per l'aplicació «{}»",
|
|
||||||
"log_user_group_add": "Afegir grup «{}»",
|
|
||||||
"log_user_group_delete": "Eliminar grup «{}»",
|
"log_user_group_delete": "Eliminar grup «{}»",
|
||||||
"log_user_group_update": "Actualitzar grup «{}»",
|
"log_user_group_update": "Actualitzar grup «{}»",
|
||||||
"log_user_permission_add": "Actualitzar el permís «{}»",
|
"mailbox_disabled": "La bústia de correu està desactivada per al usuari {user:s}",
|
||||||
"log_user_permission_remove": "Actualitzar el permís «{}»",
|
"migration_description_0011_setup_group_permission": "Configurar els grups d'usuaris i els permisos per les aplicacions i els serveis",
|
||||||
"mailbox_disabled": "La bústia de correu està desactivada per als usuaris {user:s}",
|
|
||||||
"migration_description_0011_setup_group_permission": "Configurar el grup d'usuaris i els permisos per les aplicacions i els serveis",
|
|
||||||
"migration_0011_backup_before_migration": "Creant una còpia de seguretat de la base de dades LDAP i la configuració de les aplicacions abans d'efectuar la migració.",
|
"migration_0011_backup_before_migration": "Creant una còpia de seguretat de la base de dades LDAP i la configuració de les aplicacions abans d'efectuar la migració.",
|
||||||
"migration_0011_can_not_backup_before_migration": "No s'ha pogut fer la còpia de seguretat abans de la migració. No s'ha pogut fer la migració. Error: {error:s}",
|
"migration_0011_can_not_backup_before_migration": "No s'ha pogut completar la còpia de seguretat abans de que la migració fallés. Error: {error:s}",
|
||||||
"migration_0011_create_group": "Creant un grup per a cada usuari…",
|
"migration_0011_create_group": "Creant un grup per a cada usuari…",
|
||||||
"migration_0011_done": "Migració completa. Ja podeu gestionar grups d'usuaris.",
|
"migration_0011_done": "Migració completada. Ja podeu gestionar grups d'usuaris.",
|
||||||
"migration_0011_LDAP_config_dirty": "Sembla que heu modificat manualment la configuració LDAP. Per fer aquesta migració s'ha d'actualitzar la configuració LDAP.\nGuardeu la configuració actual, reinicieu la configuració original amb l'ordre «yunohost tools regen-conf -f» i torneu a intentar la migració",
|
|
||||||
"migration_0011_LDAP_update_failed": "Ha fallat l'actualització de LDAP. Error: {error:s}",
|
"migration_0011_LDAP_update_failed": "Ha fallat l'actualització de LDAP. Error: {error:s}",
|
||||||
"migration_0011_migrate_permission": "Fent la migració dels permisos de la configuració de les aplicacions a LDAP…",
|
"migration_0011_migrate_permission": "Fent la migració dels permisos de la configuració de les aplicacions a LDAP…",
|
||||||
"migration_0011_migration_failed_trying_to_rollback": "La migració ha fallat … s'intenta tornar el sistema a l'estat anterior.",
|
"migration_0011_migration_failed_trying_to_rollback": "No s'ha pogut fer la migració… s'intenta tornar el sistema a l'estat anterior.",
|
||||||
"migration_0011_rollback_success": "S'ha tornat el sistema a l'estat anterior.",
|
"migration_0011_rollback_success": "S'ha tornat el sistema a l'estat anterior.",
|
||||||
"migration_0011_update_LDAP_database": "Actualitzant la base de dades LDAP…",
|
"migration_0011_update_LDAP_database": "Actualitzant la base de dades LDAP…",
|
||||||
"migration_0011_update_LDAP_schema": "Actualitzant l'esquema LDAP…",
|
"migration_0011_update_LDAP_schema": "Actualitzant l'esquema LDAP…",
|
||||||
"need_define_permission_before": "Heu de tornar a redefinir els permisos utilitzant «yunohost user permission add -u USER» abans d'eliminar un grup permès",
|
"permission_already_exist": "El permís «{permission:s}» ja existeix",
|
||||||
"permission_already_clear": "Ja s'ha donat el permís «{permission:s}» per l'aplicació {app:s}",
|
"permission_created": "S'ha creat el permís «{permission:s}»",
|
||||||
"permission_already_exist": "El permís «{permission:s}» ja existeix per l'aplicació {app:s}",
|
"permission_creation_failed": "No s'ha pogut crear el permís «{permission}»: {error}",
|
||||||
"permission_created": "S'ha creat el permís «{permission:s}» per l'aplicació {app:s}",
|
"permission_deleted": "S'ha eliminat el permís «{permission:s}»",
|
||||||
"permission_creation_failed": "La creació del permís ha fallat",
|
"permission_deletion_failed": "No s'ha pogut eliminar el permís «{permission:s}»: {error}",
|
||||||
"permission_deleted": "S'ha eliminat el permís «{permission:s}» per l'aplicació {app:s}",
|
"permission_not_found": "No s'ha trobat el permís «{permission:s}»",
|
||||||
"permission_deletion_failed": "L'eliminació del permís «{permission:s}» per l'aplicació {app:s} ha fallat",
|
"permission_update_failed": "No s'ha pogut actualitzar el permís «{permission}»: {error}",
|
||||||
"permission_not_found": "No s'ha trobat el permís «{permission:s}» per l'aplicació {app:s}",
|
"permission_updated": "S'ha actualitzat el permís «{permission:s}»",
|
||||||
"permission_name_not_valid": "El nom del permís «{permission:s}» no és vàlid",
|
|
||||||
"permission_update_failed": "L'actualització del permís ha fallat",
|
|
||||||
"permission_generated": "S'ha actualitzat la base de dades del permís",
|
|
||||||
"permission_updated": "S'ha actualitzat el permís «{permission:s}» per l'aplicació {app:s}",
|
|
||||||
"permission_update_nothing_to_do": "No hi ha cap permís per actualitzar",
|
"permission_update_nothing_to_do": "No hi ha cap permís per actualitzar",
|
||||||
"remove_main_permission_not_allowed": "No es pot eliminar el permís principal",
|
"migration_description_0012_postgresql_password_to_md5_authentication": "Força l'autenticació PostgreSQL a fer servir MD5 per a les connexions locals",
|
||||||
"remove_user_of_group_not_allowed": "No es pot eliminar l'usuari {user:s} del grup {group:s}",
|
"app_full_domain_unavailable": "Aquesta aplicació ha de ser instal·lada en el seu propi domini, però ja hi ha altres aplicacions instal·lades en el domini «{domain}». Podeu utilitzar un subdomini dedicat a aquesta aplicació.",
|
||||||
"system_groupname_exists": "El nom de grup ja existeix en el sistema de grups",
|
"migrations_not_pending_cant_skip": "Aquestes migracions no estan pendents, així que no poden ser omeses: {ids}",
|
||||||
"tools_update_failed_to_app_fetchlist": "No s'ha pogut actualitzar la llista d'aplicacions de YunoHost a causa de: {error}",
|
"app_action_broke_system": "Aquesta acció sembla haver trencat els següents serveis importants: {services}",
|
||||||
"user_already_in_group": "L'usuari {user:s} ja és en el grup {group:s}",
|
"log_user_group_create": "Crear grup «{}»",
|
||||||
"user_not_in_group": "L'usuari {user:s} no és en el grup {group:s}",
|
"log_user_permission_update": "Actualitzar els accessos per al permís «{}»",
|
||||||
"migration_description_0012_postgresql_password_to_md5_authentication": "Força l'autenticació postgresql a fer servir md5 per a les connexions locals"
|
"log_user_permission_reset": "Restablir el permís «{}»",
|
||||||
|
"permission_already_disallowed": "El grup «{group}» ja té el permís «{permission}» desactivat",
|
||||||
|
"migrations_already_ran": "Aquestes migracions ja s'han fet: {ids}",
|
||||||
|
"migrations_dependencies_not_satisfied": "Executeu aquestes migracions: «{dependencies_id}», abans la migració {id}.",
|
||||||
|
"migrations_failed_to_load_migration": "No s'ha pogut carregar la migració {id}: {error}",
|
||||||
|
"migrations_exclusive_options": "«--auto», «--skip», i «--force-rerun» són opcions mútuament excloents.",
|
||||||
|
"migrations_must_provide_explicit_targets": "Heu de proporcionar objectius explícits al utilitzar «--skip» o «--force-rerun»",
|
||||||
|
"migrations_no_such_migration": "No hi ha cap migració anomenada «{id}»",
|
||||||
|
"migrations_pending_cant_rerun": "Aquestes migracions encara estan pendents, així que no es poden tornar a executar: {ids}",
|
||||||
|
"migrations_running_forward": "Executant la migració {id}…",
|
||||||
|
"migrations_success_forward": "Migració {id} completada",
|
||||||
|
"apps_already_up_to_date": "Ja estan actualitzades totes les aplicacions",
|
||||||
|
"dyndns_provider_unreachable": "No s'ha pogut connectar amb el proveïdor DynDNS {provider}: o el vostre YunoHost no està ben connectat a Internet o el servidor dynette està caigut.",
|
||||||
|
"operation_interrupted": "S'ha interromput manualment l'operació?",
|
||||||
|
"group_already_exist": "El grup {group} ja existeix",
|
||||||
|
"group_already_exist_on_system": "El grup {group} ja existeix en els grups del sistema",
|
||||||
|
"group_cannot_be_deleted": "El grup {group} no es pot eliminar manualment.",
|
||||||
|
"group_user_already_in_group": "L'usuari {user} ja està en el grup {group}",
|
||||||
|
"group_user_not_in_group": "L'usuari {user} no està en el grup {group}",
|
||||||
|
"log_permission_create": "Crear el permís «{}»",
|
||||||
|
"log_permission_delete": "Eliminar el permís «{}»",
|
||||||
|
"migration_0011_failed_to_remove_stale_object": "No s'ha pogut eliminar l'objecte obsolet {dn}: {error}",
|
||||||
|
"permission_already_allowed": "El grup «{group}» ja té el permís «{permission}» activat",
|
||||||
|
"permission_cannot_remove_main": "No es permet eliminar un permís principal",
|
||||||
|
"user_already_exists": "L'usuari «{user}» ja existeix",
|
||||||
|
"app_install_failed": "No s'ha pogut instal·lar {app}: {error}",
|
||||||
|
"app_install_script_failed": "Hi ha hagut un error en el script d'instal·lació de l'aplicació",
|
||||||
|
"group_cannot_edit_all_users": "El grup «all_users» no es pot editar manualment. És un grup especial destinat a contenir els usuaris registrats a YunoHost",
|
||||||
|
"group_cannot_edit_visitors": "El grup «visitors» no es pot editar manualment. És un grup especial que representa els visitants anònims",
|
||||||
|
"group_cannot_edit_primary_group": "El grup «{group}» no es pot editar manualment. És el grup principal destinat a contenir un usuari específic.",
|
||||||
|
"log_permission_url": "Actualització de la URL associada al permís «{}»",
|
||||||
|
"migration_0011_slapd_config_will_be_overwritten": "Sembla que heu modificat manualment la configuració de sldap. Per aquesta migració crítica, YunoHost ha de forçar l'actualització de la configuració sldap. Es farà una còpia de seguretat a {conf_backup_folder}.",
|
||||||
|
"permission_already_up_to_date": "No s'ha actualitzat el permís perquè la petició d'afegir/eliminar ja corresponent a l'estat actual.",
|
||||||
|
"permission_currently_allowed_for_all_users": "El permís ha el té el grup de tots els usuaris (all_users) a més d'altres grups. Segurament s'hauria de revocar el permís a «all_users» o eliminar els altres grups als que s'ha atribuït.",
|
||||||
|
"permission_require_account": "El permís {permission} només té sentit per als usuaris que tenen un compte, i per tant no es pot activar per als visitants.",
|
||||||
|
"app_remove_after_failed_install": "Eliminant l'aplicació després que hagi fallat la instal·lació…",
|
||||||
|
"diagnosis_basesystem_ynh_main_version": "El servidor funciona amb YunoHost {main_version} ({repo})",
|
||||||
|
"diagnosis_ram_low": "El sistema només té {available} ({available_percent}%) de memòria RAM disponibles d'un total de {total}. Aneu amb compte.",
|
||||||
|
"diagnosis_swap_none": "El sistema no té swap. Hauríeu de considerar afegir un mínim de {recommended} de swap per evitar situacions en les que el sistema es queda sense memòria.",
|
||||||
|
"diagnosis_regenconf_manually_modified": "El fitxer de configuració {file} ha estat modificat manualment.",
|
||||||
|
"diagnosis_security_vulnerable_to_meltdown_details": "Per arreglar-ho, hauríeu d'actualitzar i reiniciar el sistema per tal de carregar el nou nucli de linux (o contactar amb el proveïdor del servidor si no funciona). Vegeu https://meltdownattack.com/ per a més informació.",
|
||||||
|
"diagnosis_http_could_not_diagnose": "No s'ha pogut diagnosticar si el domini és accessible des de l'exterior.",
|
||||||
|
"diagnosis_http_could_not_diagnose_details": "Error: {error}",
|
||||||
|
"domain_cannot_remove_main_add_new_one": "No es pot eliminar «{domain:s}» ja que és el domini principal i únic domini, primer s'ha d'afegir un altre domini utilitzant «yunohost domain add <un-altre-domini.com>», i després fer-lo el domini principal amb «yunohost domain main-domain -n <un-altre-domini.com>» i després es pot eliminar el domini «{domain:s}» utilitzant «yunohost domain remove {domain:s}».",
|
||||||
|
"diagnosis_basesystem_host": "El servidor funciona amb Debian {debian_version}",
|
||||||
|
"diagnosis_basesystem_kernel": "El servidor funciona amb el nucli de Linux {kernel_version}",
|
||||||
|
"diagnosis_basesystem_ynh_single_version": "{package} versió: {version}({repo})",
|
||||||
|
"diagnosis_basesystem_ynh_inconsistent_versions": "Esteu utilitzant versions inconsistents dels paquets de YunoHost… probablement a causa d'una actualització fallida o parcial.",
|
||||||
|
"diagnosis_display_tip_web": "Podeu anar a la secció de Diagnòstics (en la pantalla principal) per veure els errors que s'han trobat.",
|
||||||
|
"diagnosis_failed_for_category": "Ha fallat el diagnòstic per la categoria «{category}»: {error}",
|
||||||
|
"diagnosis_display_tip_cli": "Podeu executar «yunohost diagnosis show --issues» per mostrar els errors que s'han trobat.",
|
||||||
|
"diagnosis_cache_still_valid": "(La memòria cau encara és vàlida pel diagnòstic de {category}. No es tornar a diagnosticar de moment!)",
|
||||||
|
"diagnosis_cant_run_because_of_dep": "No es pot fer el diagnòstic per {category} mentre hi ha problemes importants relacionats amb {dep}.",
|
||||||
|
"diagnosis_ignored_issues": "(+ {nb_ignored} problema(es) ignorat(s))",
|
||||||
|
"diagnosis_found_errors": "S'ha trobat problema(es) important(s) {errors} relacionats amb {category}!",
|
||||||
|
"diagnosis_found_errors_and_warnings": "S'ha trobat problema(es) important(s) {errors} (i avis(os) {warnings}) relacionats amb {category}!",
|
||||||
|
"diagnosis_found_warnings": "S'han trobat ítems {warnings} que es podrien millorar per {category}.",
|
||||||
|
"diagnosis_everything_ok": "Tot sembla correcte per {category}!",
|
||||||
|
"diagnosis_failed": "No s'han pogut obtenir els resultats del diagnòstic per la categoria «{category}»: {error}",
|
||||||
|
"diagnosis_ip_connected_ipv4": "El servidor està connectat a Internet amb IPv4!",
|
||||||
|
"diagnosis_ip_no_ipv4": "El servidor no té una IPv4 que funcioni.",
|
||||||
|
"diagnosis_ip_connected_ipv6": "El servidor està connectat a Internet amb IPv6!",
|
||||||
|
"diagnosis_ip_no_ipv6": "El servidor no té una IPv6 que funcioni.",
|
||||||
|
"diagnosis_ip_not_connected_at_all": "Sembla que el servidor no està connectat a internet!?",
|
||||||
|
"diagnosis_ip_dnsresolution_working": "La resolució de nom de domini està funcionant!",
|
||||||
|
"diagnosis_ip_broken_dnsresolution": "La resolució de nom de domini falla per algun motiu… Està el tallafocs bloquejant les peticions DNS?",
|
||||||
|
"diagnosis_ip_broken_resolvconf": "La resolució de nom de domini sembla caiguda en el servidor, podria estar relacionat amb el fet que /etc/resolv.conf no apunta cap a 127.0.0.1.",
|
||||||
|
"diagnosis_ip_weird_resolvconf": "La resolució DNS sembla estar funcionant, però aneu amb compte ja que esteu utilitzant un versió personalitzada de /etc/resolv.conf.",
|
||||||
|
"diagnosis_ip_weird_resolvconf_details": "En canvi, aquest fitxer hauria de ser un enllaç simbòlic cap a /etc/resolvconf/run/resolv.conf i que aquest apunti cap a 127.0.0.1 (dnsmasq). La configuració del «resolver» real s'hauria de fer a /etc/resolv.dnsmaq.conf.",
|
||||||
|
"diagnosis_dns_good_conf": "Bona configuració DNS pel domini {domain} (categoria {category})",
|
||||||
|
"diagnosis_dns_bad_conf": "Configuració DNS incorrecta o inexistent pel domini {domain} (categoria {category})",
|
||||||
|
"diagnosis_dns_missing_record": "Segons la configuració DNS recomanada, hauríeu d'afegir un registre DNS\ntipus: {type}\nnom: {name}\nvalor: {value}.",
|
||||||
|
"diagnosis_dns_discrepancy": "El registre DNS de tipus {type} i nom {name} no concorda amb la configuració recomanada.\nValor actual: {current}\nValor esperat: {value}",
|
||||||
|
"diagnosis_services_bad_status": "El servei {service} està {status} :(",
|
||||||
|
"diagnosis_diskusage_verylow": "El lloc d'emmagatzematge {mountpoint} (en l'aparell {device}) només té disponibles {free} ({free_percent}%). Hauríeu de considerar alliberar una mica d'espai.",
|
||||||
|
"diagnosis_diskusage_low": "El lloc d'emmagatzematge {mountpoint} (en l'aparell {device}) només té disponibles {free} ({free_percent}%). Aneu amb compte.",
|
||||||
|
"diagnosis_diskusage_ok": "El lloc d'emmagatzematge {mountpoint} (en l'aparell {device}) encara té {free} ({free_percent}%) lliures!",
|
||||||
|
"diagnosis_ram_verylow": "El sistema només té {available} ({available_percent}%) de memòria RAM disponibles! (d'un total de {total})",
|
||||||
|
"diagnosis_ram_ok": "El sistema encara té {available} ({available_percent}%) de memòria RAM disponibles d'un total de {total}.",
|
||||||
|
"diagnosis_swap_notsomuch": "El sistema només té {total} de swap. Hauríeu de considerar tenir un mínim de {recommended} per evitar situacions en les que el sistema es queda sense memòria.",
|
||||||
|
"diagnosis_swap_ok": "El sistema té {total} de swap!",
|
||||||
|
"diagnosis_regenconf_allgood": "Tots els fitxers de configuració estan en acord amb la configuració recomanada!",
|
||||||
|
"diagnosis_regenconf_manually_modified_details": "No hauria de ser cap problema sempre i quan sapigueu el que esteu fent ;) !",
|
||||||
|
"diagnosis_regenconf_manually_modified_debian": "El fitxer de configuració {file} ha estat modificat manualment respecte al fitxer per defecte de Debian.",
|
||||||
|
"diagnosis_regenconf_manually_modified_debian_details": "No hauria de ser cap problema, però ho haureu de vigilar...",
|
||||||
|
"diagnosis_security_all_good": "No s'ha trobat cap vulnerabilitat de seguretat crítica.",
|
||||||
|
"diagnosis_security_vulnerable_to_meltdown": "Sembla que el sistema és vulnerable a la vulnerabilitat de seguretat crítica Meltdown",
|
||||||
|
"diagnosis_description_basesystem": "Sistema de base",
|
||||||
|
"diagnosis_description_ip": "Connectivitat a Internet",
|
||||||
|
"diagnosis_description_dnsrecords": "Registres DNS",
|
||||||
|
"diagnosis_description_services": "Verificació de l'estat dels serveis",
|
||||||
|
"diagnosis_description_systemresources": "Recursos del sistema",
|
||||||
|
"diagnosis_description_ports": "Exposició dels ports",
|
||||||
|
"diagnosis_description_regenconf": "Configuració del sistema",
|
||||||
|
"diagnosis_description_security": "Verificacions de seguretat",
|
||||||
|
"diagnosis_ports_could_not_diagnose": "No s'ha pogut diagnosticar si els ports són accessibles des de l'exterior.",
|
||||||
|
"diagnosis_ports_could_not_diagnose_details": "Error: {error}",
|
||||||
|
"diagnosis_ports_unreachable": "El port {port} no és accessible des de l'exterior.",
|
||||||
|
"diagnosis_ports_ok": "El port {port} és accessible des de l'exterior.",
|
||||||
|
"diagnosis_http_ok": "El domini {domain} és accessible per mitjà de HTTP des de fora de la xarxa local.",
|
||||||
|
"diagnosis_http_unreachable": "Sembla que el domini {domain} no és accessible a través de HTTP des de fora de la xarxa local.",
|
||||||
|
"diagnosis_unknown_categories": "Les següents categories són desconegudes: {categories}",
|
||||||
|
"apps_catalog_init_success": "S'ha iniciat el sistema de catàleg d'aplicacions!",
|
||||||
|
"apps_catalog_updating": "S'està actualitzant el catàleg d'aplicacions…",
|
||||||
|
"apps_catalog_failed_to_download": "No s'ha pogut descarregar el catàleg d'aplicacions {apps_catalog}: {error}",
|
||||||
|
"apps_catalog_obsolete_cache": "La memòria cau del catàleg d'aplicacions és buida o obsoleta.",
|
||||||
|
"apps_catalog_update_success": "S'ha actualitzat el catàleg d'aplicacions!",
|
||||||
|
"diagnosis_mail_ougoing_port_25_ok": "El port de sortida 25 no està bloquejat i els correus es poden enviar a altres servidors.",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked": "Sembla que el port de sortida 25 està bloquejat. Hauríeu d'intentar desbloquejar-lo al panell de configuració del proveïdor d'accés a internet (o allotjador). Mentrestant, el servidor no podrà enviar correus a altres servidors.",
|
||||||
|
"diagnosis_description_mail": "Correu electrònic",
|
||||||
|
"migration_description_0013_futureproof_apps_catalog_system": "Migrar al nou sistema de catàleg d'aplicacions resistent al pas del temps",
|
||||||
|
"app_upgrade_script_failed": "Hi ha hagut un error en el script d'actualització de l'aplicació",
|
||||||
|
"diagnosis_services_bad_status_tip": "Podeu intentar reiniciar el servei, i si no funciona, podeu mirar els registres del servei utilitzant «yunohost service log {service}» o a través de «Serveis» a la secció de la pàgina web d'administració.",
|
||||||
|
"diagnosis_ports_forwarding_tip": "Per arreglar aquest problema, segurament s'ha de configurar el reenviament de ports en el router tal i com s'explica a https://yunohost.org/isp_box_config",
|
||||||
|
"diagnosis_http_bad_status_code": "El sistema de diagnòstic no ha pogut connectar amb el servidor. Podria ser que una altra màquina hagi contestat en lloc del servidor. S'hauria de comprovar que el reenviament del port 80 sigui correcte, que la configuració NGINX està actualitzada i que el reverse-proxy no està interferint.",
|
||||||
|
"diagnosis_no_cache": "Encara no hi ha memòria cau pel diagnòstic de la categoria «{category}»",
|
||||||
|
"diagnosis_http_timeout": "S'ha exhaurit el temps d'esperar intentant connectar amb el servidor des de l'exterior. Sembla que no s'hi pot accedir. S'hauria de comprovar que el reenviament del port 80 és correcte, que NGINX funciona, i que el tallafocs no està interferint.",
|
||||||
|
"diagnosis_http_connection_error": "Error de connexió: no s'ha pogut connectar amb el domini demanat, segurament és inaccessible.",
|
||||||
|
"yunohost_postinstall_end_tip": "S'ha completat la post-instal·lació. Per acabar la configuració, considereu:\n - afegir un primer usuari a través de la secció «Usuaris» a la pàgina web d'administració (o emprant «yunohost user create <username>» a la línia d'ordres);\n - diagnosticar possibles problemes a través de la secció «Diagnòstics» a la pàgina web d'administració (o emprant «yunohost diagnosis run» a la línia d'ordres);\n - llegir les seccions «Finalizing your setup» i «Getting to know Yunohost» a la documentació per administradors: https://yunohost.org/admindoc.",
|
||||||
|
"migration_description_0014_remove_app_status_json": "Eliminar els fitxers d'aplicació status.json heretats",
|
||||||
|
"diagnosis_services_running": "El servei {service} s'està executant!",
|
||||||
|
"diagnosis_services_conf_broken": "La configuració pel servei {service} està trencada!",
|
||||||
|
"diagnosis_ports_needed_by": "És necessari exposar aquest port per a les funcions {category} (servei {service})",
|
||||||
|
"global_settings_setting_pop3_enabled": "Activa el protocol POP3 per al servidor de correu",
|
||||||
|
"log_app_action_run": "Executa l'acció de l'aplicació «{}»",
|
||||||
|
"log_app_config_show_panel": "Mostra el taulell de configuració de l'aplicació «{}»",
|
||||||
|
"log_app_config_apply": "Afegeix la configuració a l'aplicació «{}»",
|
||||||
|
"diagnosis_never_ran_yet": "Sembla que el servidor s'ha configurat recentment i encara no hi cap informe de diagnòstic per mostrar. S'ha d'executar un diagnòstic complet primer, ja sigui des de la pàgina web d'administració o utilitzant la comanda «yunohost diagnosis run» al terminal.",
|
||||||
|
"diagnosis_description_web": "Web",
|
||||||
|
"diagnosis_basesystem_hardware_board": "El model de la targeta del servidor és {model}",
|
||||||
|
"diagnosis_basesystem_hardware": "L'arquitectura del maquinari del servidor és {virt} {arch}",
|
||||||
|
"group_already_exist_on_system_but_removing_it": "El grup {group} ja existeix en els grups del sistema, però YunoHost l'eliminarà…"
|
||||||
}
|
}
|
||||||
|
|
264
locales/de.json
264
locales/de.json
|
@ -4,72 +4,52 @@
|
||||||
"admin_password_change_failed": "Passwort kann nicht geändert werden",
|
"admin_password_change_failed": "Passwort kann nicht geändert werden",
|
||||||
"admin_password_changed": "Das Administrator-Kennwort wurde geändert",
|
"admin_password_changed": "Das Administrator-Kennwort wurde geändert",
|
||||||
"app_already_installed": "{app:s} ist schon installiert",
|
"app_already_installed": "{app:s} ist schon installiert",
|
||||||
"app_argument_choice_invalid": "Verwende einen der folgenden Werte {choices:s}",
|
"app_argument_choice_invalid": "Wähle einen der folgenden Werte '{choices:s}' für das Argument '{name:s}'",
|
||||||
"app_argument_invalid": "Wähle einen gültigen Wert für das Argument '{name: s}': {error: s}",
|
"app_argument_invalid": "Wähle einen gültigen Wert für das Argument '{name:s}': {error:s}",
|
||||||
"app_argument_required": "Argument '{name:s}' wird benötigt",
|
"app_argument_required": "Argument '{name:s}' wird benötigt",
|
||||||
"app_extraction_failed": "Installationsdateien konnten nicht entpackt werden",
|
"app_extraction_failed": "Installationsdateien konnten nicht entpackt werden",
|
||||||
"app_id_invalid": "Falsche App-ID",
|
"app_id_invalid": "Falsche App-ID",
|
||||||
"app_install_files_invalid": "Diese Dateien können nicht installiert werden",
|
"app_install_files_invalid": "Diese Dateien können nicht installiert werden",
|
||||||
"app_location_already_used": "Die App ({app}) ist bereits hier ({path}) installiert",
|
|
||||||
"app_location_install_failed": "Die App kann dort nicht installiert werden, da ein Konflikt mit der App '{other_app}' besteht, die bereits in '{other_path}' installiert ist",
|
|
||||||
"app_manifest_invalid": "Mit dem App-Manifest stimmt etwas nicht: {error}",
|
"app_manifest_invalid": "Mit dem App-Manifest stimmt etwas nicht: {error}",
|
||||||
"app_no_upgrade": "Alle Apps sind bereits aktuell",
|
|
||||||
"app_not_installed": "Die App {app:s} konnte nicht in der Liste installierter Apps gefunden werden: {all_apps}",
|
"app_not_installed": "Die App {app:s} konnte nicht in der Liste installierter Apps gefunden werden: {all_apps}",
|
||||||
"app_recent_version_required": "Für {:s} benötigt eine aktuellere Version von moulinette",
|
|
||||||
"app_removed": "{app:s} wurde entfernt",
|
"app_removed": "{app:s} wurde entfernt",
|
||||||
"app_sources_fetch_failed": "Quelldateien konnten nicht abgerufen werden, ist die URL korrekt?",
|
"app_sources_fetch_failed": "Quelldateien konnten nicht abgerufen werden, ist die URL korrekt?",
|
||||||
"app_unknown": "Unbekannte App",
|
"app_unknown": "Unbekannte App",
|
||||||
"app_upgrade_failed": "{app:s} konnte nicht aktualisiert werden",
|
"app_upgrade_failed": "{app:s} konnte nicht aktualisiert werden",
|
||||||
"app_upgraded": "{app:s} wurde erfolgreich aktualisiert",
|
"app_upgraded": "{app:s} aktualisiert",
|
||||||
"appslist_fetched": "Appliste {appslist:s} wurde erfolgreich heruntergelanden",
|
|
||||||
"appslist_removed": "Appliste {appslist:s} wurde erfolgreich entfernt",
|
|
||||||
"appslist_retrieve_error": "Entfernte Appliste {appslist:s} kann nicht empfangen werden: {error:s}",
|
|
||||||
"appslist_unknown": "Appliste {appslist:s} ist unbekannt.",
|
|
||||||
"ask_current_admin_password": "Derzeitiges Administrator-Kennwort",
|
|
||||||
"ask_email": "E-Mail-Adresse",
|
"ask_email": "E-Mail-Adresse",
|
||||||
"ask_firstname": "Vorname",
|
"ask_firstname": "Vorname",
|
||||||
"ask_lastname": "Nachname",
|
"ask_lastname": "Nachname",
|
||||||
"ask_list_to_remove": "zu entfernende Liste",
|
|
||||||
"ask_main_domain": "Hauptdomain",
|
"ask_main_domain": "Hauptdomain",
|
||||||
"ask_new_admin_password": "Neues Verwaltungskennwort",
|
"ask_new_admin_password": "Neues Verwaltungskennwort",
|
||||||
"ask_password": "Passwort",
|
"ask_password": "Passwort",
|
||||||
"backup_action_required": "Du musst etwas zum Speichern auswählen",
|
"backup_app_failed": "Konnte keine Sicherung für die App '{app:s}' erstellen",
|
||||||
"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_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_exists": "Datensicherung mit dem selben Namen existiert bereits",
|
|
||||||
"backup_archive_name_unknown": "Unbekanntes lokale Datensicherung mit Namen '{name:s}' gefunden",
|
"backup_archive_name_unknown": "Unbekanntes lokale Datensicherung mit Namen '{name:s}' gefunden",
|
||||||
"backup_archive_open_failed": "Kann Sicherungsarchiv nicht öfnen",
|
"backup_archive_open_failed": "Kann Sicherungsarchiv nicht öfnen",
|
||||||
"backup_cleaning_failed": "Temporäres Sicherungsverzeichnis konnte nicht geleert werden",
|
"backup_cleaning_failed": "Temporäres Sicherungsverzeichnis konnte nicht geleert werden",
|
||||||
"backup_created": "Datensicherung komplett",
|
"backup_created": "Datensicherung komplett",
|
||||||
"backup_creating_archive": "Datensicherung wird erstellt…",
|
|
||||||
"backup_delete_error": "Pfad '{path:s}' konnte nicht gelöscht werden",
|
"backup_delete_error": "Pfad '{path:s}' konnte nicht gelöscht werden",
|
||||||
"backup_deleted": "Datensicherung wurde entfernt",
|
"backup_deleted": "Backup wurde entfernt",
|
||||||
"backup_extracting_archive": "Entpacke Sicherungsarchiv...",
|
"backup_hook_unknown": "Der Datensicherungshook '{hook:s}' unbekannt",
|
||||||
"backup_hook_unknown": "Datensicherungshook '{hook:s}' unbekannt",
|
"backup_invalid_archive": "Dies ist kein Backup-Archiv",
|
||||||
"backup_invalid_archive": "Ungültige Datensicherung",
|
"backup_nothings_done": "Keine Änderungen zur Speicherung",
|
||||||
"backup_nothings_done": "Es gibt keine Änderungen zur Speicherung",
|
"backup_output_directory_forbidden": "Wähle ein anderes Ausgabeverzeichnis. Datensicherung können nicht in /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var oder in Unterordnern von /home/yunohost.backup/archives erstellt werden",
|
||||||
"backup_output_directory_forbidden": "Verbotenes Ausgabeverzeichnis. Datensicherung können nicht in /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var oder in Unterordnern von /home/yunohost.backup/archives erstellt werden",
|
"backup_output_directory_not_empty": "Der gewählte Ausgabeordner sollte leer sein",
|
||||||
"backup_output_directory_not_empty": "Ausgabeordner ist nicht leer",
|
|
||||||
"backup_output_directory_required": "Für die Datensicherung muss ein Zielverzeichnis angegeben werden",
|
"backup_output_directory_required": "Für die Datensicherung muss ein Zielverzeichnis angegeben werden",
|
||||||
"backup_running_app_script": "Datensicherung für App '{app:s}' wurd durchgeführt...",
|
|
||||||
"backup_running_hooks": "Datensicherunghook wird ausgeführt…",
|
"backup_running_hooks": "Datensicherunghook wird ausgeführt…",
|
||||||
"custom_app_url_required": "Es muss eine URL angegeben werden, um deine benutzerdefinierte App {app:s} zu aktualisieren",
|
"custom_app_url_required": "Es muss eine URL angegeben werden, 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_cert_gen_failed": "Zertifikat konnte nicht erzeugt werden",
|
||||||
"domain_created": "Die Domain wurde angelegt",
|
"domain_created": "Die Domain wurde angelegt",
|
||||||
"domain_creation_failed": "Konnte Domain nicht erzeugen",
|
"domain_creation_failed": "Konnte Domain nicht erzeugen",
|
||||||
"domain_deleted": "Die Domain wurde gelöscht",
|
"domain_deleted": "Die Domain wurde gelöscht",
|
||||||
"domain_deletion_failed": "Konnte Domain nicht löschen",
|
"domain_deletion_failed": "Konnte Domain nicht löschen",
|
||||||
"domain_dyndns_already_subscribed": "Du hast dich schon für eine DynDNS-Domain angemeldet",
|
"domain_dyndns_already_subscribed": "Du hast dich schon für eine DynDNS-Domain angemeldet",
|
||||||
"domain_dyndns_invalid": "Domain nicht mittels DynDNS nutzbar",
|
|
||||||
"domain_dyndns_root_unknown": "Unbekannte DynDNS Hauptdomain",
|
"domain_dyndns_root_unknown": "Unbekannte DynDNS Hauptdomain",
|
||||||
"domain_exists": "Die Domain existiert bereits",
|
"domain_exists": "Die Domain existiert bereits",
|
||||||
"domain_uninstall_app_first": "Mindestens eine App ist noch für diese Domain installiert. Bitte deinstalliere zuerst die App, bevor du die Domain löschst",
|
"domain_uninstall_app_first": "Mindestens eine App ist noch für diese Domain installiert. Bitte deinstalliere zuerst die App, bevor du die Domain löschst",
|
||||||
"domain_unknown": "Unbekannte Domain",
|
"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",
|
"done": "Erledigt",
|
||||||
"downloading": "Wird heruntergeladen…",
|
"downloading": "Wird heruntergeladen…",
|
||||||
"dyndns_cron_installed": "DynDNS Cronjob erfolgreich angelegt",
|
"dyndns_cron_installed": "DynDNS Cronjob erfolgreich angelegt",
|
||||||
|
@ -88,9 +68,6 @@
|
||||||
"firewall_reload_failed": "Die Firewall konnte nicht neu geladen werden",
|
"firewall_reload_failed": "Die Firewall konnte nicht neu geladen werden",
|
||||||
"firewall_reloaded": "Die Firewall wurde neu geladen",
|
"firewall_reloaded": "Die Firewall wurde neu geladen",
|
||||||
"firewall_rules_cmd_failed": "Einzelne Firewallregeln konnten nicht übernommen werden. Mehr Informationen sind im Log zu finden.",
|
"firewall_rules_cmd_failed": "Einzelne Firewallregeln konnten nicht übernommen werden. Mehr Informationen sind im Log zu finden.",
|
||||||
"format_datetime_short": "%d/%m/%Y %I:%M %p",
|
|
||||||
"hook_argument_missing": "Fehlend Argument '{:s}'",
|
|
||||||
"hook_choice_invalid": "ungültige Wahl '{:s}'",
|
|
||||||
"hook_exec_failed": "Skriptausführung fehlgeschlagen: {path:s}",
|
"hook_exec_failed": "Skriptausführung fehlgeschlagen: {path:s}",
|
||||||
"hook_exec_not_terminated": "Skriptausführung noch nicht beendet: {path:s}",
|
"hook_exec_not_terminated": "Skriptausführung noch nicht beendet: {path:s}",
|
||||||
"hook_list_by_invalid": "Ungültiger Wert zur Anzeige von Hooks",
|
"hook_list_by_invalid": "Ungültiger Wert zur Anzeige von Hooks",
|
||||||
|
@ -100,53 +77,24 @@
|
||||||
"ip6tables_unavailable": "ip6tables kann nicht verwendet werden. Du befindest dich entweder in einem Container oder es wird nicht vom Kernel unterstützt",
|
"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",
|
"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 wurde initialisiert",
|
"ldap_initialized": "LDAP wurde initialisiert",
|
||||||
"license_undefined": "Undeiniert",
|
|
||||||
"mail_alias_remove_failed": "E-Mail Alias '{mail:s}' konnte nicht entfernt werden",
|
"mail_alias_remove_failed": "E-Mail Alias '{mail:s}' konnte nicht entfernt werden",
|
||||||
"mail_domain_unknown": "Unbekannte Mail Domain '{domain:s}'",
|
"mail_domain_unknown": "Unbekannte Mail Domain '{domain:s}'",
|
||||||
"mail_forward_remove_failed": "Mailweiterleitung '{mail:s}' konnte nicht entfernt werden",
|
"mail_forward_remove_failed": "Mailweiterleitung '{mail:s}' konnte nicht entfernt werden",
|
||||||
"maindomain_change_failed": "Die Hauptdomain konnte nicht geändert werden",
|
"main_domain_change_failed": "Die Hauptdomain konnte nicht geändert werden",
|
||||||
"maindomain_changed": "Die Hauptdomain wurde geändert",
|
"main_domain_changed": "Die Hauptdomain wurde geändert",
|
||||||
"monitor_disabled": "Das Servermonitoring wurde erfolgreich deaktiviert",
|
|
||||||
"monitor_enabled": "Das Servermonitoring wurde 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": "Die MySQL Datenbank wurde 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_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": "Ein wichtiges Paket ({packages:s}) wird später aktualisiert",
|
|
||||||
"packages_upgrade_failed": "Es konnten nicht alle Pakete aktualisiert werden",
|
"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 maximal 30 alphanumerischen sowie -_. Zeichen bestehen",
|
"pattern_backup_archive_name": "Ein gültiger Dateiname kann nur aus maximal 30 alphanumerischen sowie -_. Zeichen bestehen",
|
||||||
"pattern_domain": "Muss ein gültiger Domainname sein (z.B. meine-domain.org)",
|
"pattern_domain": "Muss ein gültiger Domainname sein (z.B. meine-domain.org)",
|
||||||
"pattern_email": "Muss eine gültige E-Mail Adresse sein (z.B. someone@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_firstname": "Muss ein gültiger Vorname sein",
|
||||||
"pattern_lastname": "Muss ein gültiger Nachname 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_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_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_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",
|
"pattern_username": "Darf nur aus klein geschriebenen alphanumerischen Zeichen und Unterstrichen bestehen",
|
||||||
"port_already_closed": "Der Port {port:d} wurde bereits für {ip_version:s} Verbindungen geschlossen",
|
"port_already_closed": "Der 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_already_opened": "Der Port {port:d} wird bereits von {ip_version:s} benutzt",
|
||||||
"port_available": "Der 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_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_app_failed": "App '{app:s}' konnte nicht wiederhergestellt werden",
|
||||||
"restore_cleaning_failed": "Das temporäre Wiederherstellungsverzeichnis konnte nicht geleert werden",
|
"restore_cleaning_failed": "Das temporäre Wiederherstellungsverzeichnis konnte nicht geleert werden",
|
||||||
|
@ -157,38 +105,30 @@
|
||||||
"restore_nothings_done": "Es wurde nicht wiederhergestellt",
|
"restore_nothings_done": "Es wurde nicht wiederhergestellt",
|
||||||
"restore_running_app_script": "Wiederherstellung wird ausfeührt für App '{app:s}'...",
|
"restore_running_app_script": "Wiederherstellung wird ausfeührt für App '{app:s}'...",
|
||||||
"restore_running_hooks": "Wiederherstellung wird gestartet…",
|
"restore_running_hooks": "Wiederherstellung wird gestartet…",
|
||||||
"service_add_configuration": "Füge Konfigurationsdatei {file:s} hinzu",
|
|
||||||
"service_add_failed": "Der Dienst '{service:s}' kann nicht hinzugefügt werden",
|
"service_add_failed": "Der Dienst '{service:s}' kann nicht hinzugefügt werden",
|
||||||
"service_added": "Der Service '{service:s}' wurde erfolgreich hinzugefügt",
|
"service_added": "Der Service '{service:s}' wurde erfolgreich hinzugefügt",
|
||||||
"service_already_started": "Der Dienst '{service:s}' läuft bereits",
|
"service_already_started": "Der Dienst '{service:s}' läuft bereits",
|
||||||
"service_already_stopped": "Dienst '{service:s}' wurde bereits gestoppt",
|
"service_already_stopped": "Dienst '{service:s}' wurde bereits gestoppt",
|
||||||
"service_cmd_exec_failed": "Der Befehl '{command:s}' konnte nicht ausgeführt werden",
|
"service_cmd_exec_failed": "Der Befehl '{command:s}' konnte 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": "Der Dienst '{service:s}' konnte nicht deaktiviert werden",
|
"service_disable_failed": "Der Dienst '{service:s}' konnte nicht deaktiviert werden",
|
||||||
"service_disabled": "Der Dienst '{service:s}' wurde erfolgreich deaktiviert",
|
"service_disabled": "Der Dienst '{service:s}' wurde erfolgreich deaktiviert",
|
||||||
"service_enable_failed": "Der Dienst '{service:s}' konnte nicht aktiviert werden",
|
"service_enable_failed": "Der Dienst '{service:s}' konnte nicht aktiviert werden",
|
||||||
"service_enabled": "Der Dienst '{service:s}' wurde erfolgreich aktiviert",
|
"service_enabled": "Der Dienst '{service:s}' wurde erfolgreich aktiviert",
|
||||||
"service_no_log": "Für den Dienst '{service:s}' kann kein Log angezeigt werden",
|
|
||||||
"service_remove_failed": "Der Dienst '{service:s}' konnte nicht entfernt werden",
|
"service_remove_failed": "Der Dienst '{service:s}' konnte nicht entfernt werden",
|
||||||
"service_removed": "Der Dienst '{service:s}' wurde erfolgreich entfernt",
|
"service_removed": "Der Dienst '{service:s}' wurde erfolgreich entfernt",
|
||||||
"service_start_failed": "Der Dienst '{service:s}' konnte nicht gestartet werden",
|
"service_start_failed": "Der Dienst '{service:s}' konnte nicht gestartet werden",
|
||||||
"service_started": "Der Dienst '{service:s}' wurde erfolgreich gestartet",
|
"service_started": "Der Dienst '{service:s}' wurde erfolgreich gestartet",
|
||||||
"service_status_failed": "Der Status von '{service:s}' kann nicht festgestellt werden",
|
|
||||||
"service_stop_failed": "Der Dienst '{service:s}' kann nicht gestoppt werden",
|
"service_stop_failed": "Der Dienst '{service:s}' kann nicht gestoppt werden",
|
||||||
"service_stopped": "Der Dienst '{service:s}' wurde erfolgreich beendet",
|
"service_stopped": "Der Dienst '{service:s}' wurde erfolgreich beendet",
|
||||||
"service_unknown": "Unbekannter Dienst '{service:s}'",
|
"service_unknown": "Unbekannter Dienst '{service:s}'",
|
||||||
"services_configured": "Konfiguration erfolgreich erstellt",
|
|
||||||
"show_diff": "Es gibt folgende Änderungen:\n{diff:s}",
|
|
||||||
"ssowat_conf_generated": "Die Konfiguration von SSOwat war erfolgreich",
|
"ssowat_conf_generated": "Die Konfiguration von SSOwat war erfolgreich",
|
||||||
"ssowat_conf_updated": "Die persistente SSOwat Einstellung wurde aktualisiert",
|
"ssowat_conf_updated": "Die persistente SSOwat Einstellung wurde aktualisiert",
|
||||||
"system_upgraded": "Das System wurde aktualisiert",
|
"system_upgraded": "Das System wurde aktualisiert",
|
||||||
"system_username_exists": "Der Benutzername existiert bereits",
|
"system_username_exists": "Der Benutzername existiert bereits",
|
||||||
"unbackup_app": "App '{app:s}' konnte nicht gespeichert werden",
|
"unbackup_app": "App '{app:s}' konnte nicht gespeichert werden",
|
||||||
"unexpected_error": "Ein unerwarteter Fehler ist aufgetreten",
|
"unexpected_error": "Ein unerwarteter Fehler ist aufgetreten",
|
||||||
"unit_unknown": "Unbekannte Einheit '{unit:s}'",
|
|
||||||
"unlimit": "Kein Kontingent",
|
"unlimit": "Kein Kontingent",
|
||||||
"unrestore_app": "App '{app:s}' kann nicht Wiederhergestellt werden",
|
"unrestore_app": "App '{app:s}' kann nicht Wiederhergestellt werden",
|
||||||
"update_cache_failed": "Konnte APT cache nicht aktualisieren",
|
|
||||||
"updating_apt_cache": "Die Liste der verfügbaren Pakete wird aktualisiert…",
|
"updating_apt_cache": "Die Liste der verfügbaren Pakete wird aktualisiert…",
|
||||||
"upgrade_complete": "Upgrade vollständig",
|
"upgrade_complete": "Upgrade vollständig",
|
||||||
"upgrading_packages": "Pakete werden aktualisiert…",
|
"upgrading_packages": "Pakete werden aktualisiert…",
|
||||||
|
@ -201,7 +141,6 @@
|
||||||
"user_deleted": "Der Benutzer wurde entfernt",
|
"user_deleted": "Der Benutzer wurde entfernt",
|
||||||
"user_deletion_failed": "Nutzer konnte nicht gelöscht werden",
|
"user_deletion_failed": "Nutzer konnte nicht gelöscht werden",
|
||||||
"user_home_creation_failed": "Benutzer Home konnte nicht erstellt 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:s}",
|
"user_unknown": "Unbekannter Benutzer: {user:s}",
|
||||||
"user_update_failed": "Benutzer kann nicht aktualisiert werden",
|
"user_update_failed": "Benutzer kann nicht aktualisiert werden",
|
||||||
"user_updated": "Der Benutzer wurde aktualisiert",
|
"user_updated": "Der Benutzer wurde aktualisiert",
|
||||||
|
@ -211,59 +150,33 @@
|
||||||
"yunohost_installing": "YunoHost wird installiert…",
|
"yunohost_installing": "YunoHost wird installiert…",
|
||||||
"yunohost_not_installed": "YunoHost ist nicht oder unvollständig installiert worden. Bitte 'yunohost tools postinstall' ausführen",
|
"yunohost_not_installed": "YunoHost ist nicht oder unvollständig installiert worden. Bitte 'yunohost tools postinstall' ausführen",
|
||||||
"app_not_properly_removed": "{app:s} wurde nicht ordnungsgemäß entfernt",
|
"app_not_properly_removed": "{app:s} wurde nicht ordnungsgemäß entfernt",
|
||||||
"service_regenconf_failed": "Konnte die Konfiguration für folgende Dienste nicht neu erzeugen: {services}",
|
|
||||||
"not_enough_disk_space": "Zu wenig freier Speicherplatz unter '{path:s}' verfügbar",
|
"not_enough_disk_space": "Zu wenig freier Speicherplatz unter '{path:s}' verfügbar",
|
||||||
"backup_creation_failed": "Erstellen des Backups fehlgeschlagen",
|
"backup_creation_failed": "Konnte Backup-Archiv nicht erstellen",
|
||||||
"service_conf_up_to_date": "Die Konfiguration für den Dienst '{service}' ist bereits aktuell",
|
|
||||||
"package_not_installed": "Das Paket '{pkgname}' ist nicht installiert",
|
|
||||||
"pattern_positive_number": "Muss eine positive Zahl sein",
|
"pattern_positive_number": "Muss eine positive Zahl sein",
|
||||||
"diagnosis_kernel_version_error": "Kann Kernelversion nicht abrufen: {error}",
|
|
||||||
"package_unexpected_error": "Ein unerwarteter Fehler trat bei der Verarbeitung des Pakets '{pkgname}' auf",
|
|
||||||
"app_incompatible": "Die Anwendung {app} ist nicht mit deiner YunoHost-Version kompatibel",
|
|
||||||
"app_not_correctly_installed": "{app:s} scheint nicht korrekt installiert zu sein",
|
"app_not_correctly_installed": "{app:s} scheint nicht korrekt installiert zu sein",
|
||||||
"app_requirements_checking": "Überprüfe notwendige Pakete für {app}…",
|
"app_requirements_checking": "Überprüfe notwendige Pakete für {app}…",
|
||||||
"app_requirements_failed": "Anforderungen für {app} werden nicht erfüllt: {error}",
|
|
||||||
"app_requirements_unmeet": "Anforderungen für {app} werden nicht erfüllt, das Paket {pkgname} ({version}) muss {spec} sein",
|
"app_requirements_unmeet": "Anforderungen für {app} werden nicht erfüllt, das Paket {pkgname} ({version}) muss {spec} sein",
|
||||||
"app_unsupported_remote_type": "Für die App wurde ein nicht unterstützer Steuerungstyp verwendet",
|
"app_unsupported_remote_type": "Für die App wurde ein nicht unterstützer Steuerungstyp verwendet",
|
||||||
"backup_archive_broken_link": "Auf das Backup-Archiv konnte nicht zugegriffen werden (ungültiger Link zu {path:s})",
|
"backup_archive_broken_link": "Auf das Backup-Archiv konnte nicht zugegriffen werden (ungültiger Link zu {path:s})",
|
||||||
"diagnosis_debian_version_error": "Debian Version konnte nicht abgerufen werden: {error}",
|
|
||||||
"diagnosis_monitor_disk_error": "Festplatten können nicht aufgelistet werden: {error}",
|
|
||||||
"diagnosis_monitor_network_error": "Netzwerk kann nicht angezeigt werden: {error}",
|
|
||||||
"diagnosis_monitor_system_error": "System kann nicht angezeigt werden: {error}",
|
|
||||||
"diagnosis_no_apps": "Keine Anwendung ist installiert",
|
|
||||||
"domains_available": "Verfügbare Domains:",
|
"domains_available": "Verfügbare Domains:",
|
||||||
"dyndns_key_not_found": "DNS-Schlüssel für die Domain wurde nicht gefunden",
|
"dyndns_key_not_found": "DNS-Schlüssel für die Domain wurde nicht gefunden",
|
||||||
"dyndns_no_domain_registered": "Es wurde keine Domain mit DynDNS registriert",
|
"dyndns_no_domain_registered": "Es wurde keine Domain mit DynDNS registriert",
|
||||||
"ldap_init_failed_to_create_admin": "Die LDAP Initialisierung konnte keinen admin Benutzer erstellen",
|
"ldap_init_failed_to_create_admin": "Die LDAP Initialisierung konnte keinen admin Benutzer erstellen",
|
||||||
"mailbox_used_space_dovecot_down": "Der Dovecot Mailbox Dienst muss gestartet sein, wenn du den von der Mailbox belegten Speicher angezeigen lassen willst",
|
"mailbox_used_space_dovecot_down": "Der Dovecot Mailbox Dienst muss gestartet sein, wenn du den von der Mailbox belegten Speicher angezeigen lassen willst",
|
||||||
"package_unknown": "Unbekanntes Paket '{pkgname}'",
|
"package_unknown": "Unbekanntes Paket '{pkgname}'",
|
||||||
"service_conf_file_backed_up": "Von der Konfigurationsdatei {conf} wurde ein Backup in {backup} erstellt",
|
|
||||||
"service_conf_file_copy_failed": "Die neue Konfigurationsdatei konnte von {new} nach {conf} nicht kopiert werden",
|
|
||||||
"service_conf_file_manually_modified": "Die Konfigurationsdatei {conf} wurde manuell verändert und wird nicht aktualisiert",
|
|
||||||
"service_conf_file_manually_removed": "Die Konfigurationsdatei {conf} wurde manuell entfern und wird nicht erstellt",
|
|
||||||
"service_conf_file_not_managed": "Die Konfigurationsdatei {conf} wurde noch nicht verwaltet und wird nicht aktualisiert",
|
|
||||||
"service_conf_file_remove_failed": "Die Konfigurationsdatei {conf} konnte nicht entfernt werden",
|
|
||||||
"service_conf_file_removed": "Die Konfigurationsdatei {conf} wurde entfernt",
|
|
||||||
"service_conf_file_updated": "Die Konfigurationsdatei {conf} wurde aktualisiert",
|
|
||||||
"service_conf_updated": "Die Konfigurationsdatei wurde für den Service {service} aktualisiert",
|
|
||||||
"service_conf_would_be_updated": "Die Konfigurationsdatei sollte für den Service {service} aktualisiert werden",
|
|
||||||
"ssowat_persistent_conf_read_error": "Ein Fehler ist aufgetreten, als die persistente SSOwat Konfiguration eingelesen wurde {error:s} Bearbeite die persistente Datei /etc/ssowat/conf.json , um die JSON syntax zu korregieren",
|
|
||||||
"ssowat_persistent_conf_write_error": "Ein Fehler ist aufgetreten, als die persistente SSOwat Konfiguration gespeichert wurde {error:s} Bearbeite die persistente Datei /etc/ssowat/conf.json , um die JSON syntax zu korregieren",
|
|
||||||
"certmanager_attempt_to_replace_valid_cert": "Du versuchst gerade eine richtiges und gültiges Zertifikat der Domain {domain:s} zu überschreiben! (Benutze --force , um diese Nachricht zu umgehen)",
|
"certmanager_attempt_to_replace_valid_cert": "Du versuchst gerade eine richtiges und gültiges Zertifikat der Domain {domain:s} zu überschreiben! (Benutze --force , um diese Nachricht zu umgehen)",
|
||||||
"certmanager_domain_unknown": "Unbekannte Domain {domain:s}",
|
"certmanager_domain_unknown": "Unbekannte Domain {domain:s}",
|
||||||
"certmanager_domain_cert_not_selfsigned": "Das Zertifikat der Domain {domain:s} is kein selbstsigniertes Zertifikat. Bist du dir sicher, dass du es ersetzen willst? (Benutze --force)",
|
"certmanager_domain_cert_not_selfsigned": "Das Zertifikat der Domain {domain:s} is kein selbstsigniertes Zertifikat. Bist du dir sicher, dass du es ersetzen willst? (Benutze --force)",
|
||||||
"certmanager_certificate_fetching_or_enabling_failed": "Es scheint so als wäre die Aktivierung des Zertifikats für die Domain {domain:s} fehlgeschlagen...",
|
"certmanager_certificate_fetching_or_enabling_failed": "Es scheint so als wäre die Aktivierung des Zertifikats für die Domain {domain:s} fehlgeschlagen...",
|
||||||
"certmanager_attempt_to_renew_nonLE_cert": "Das Zertifikat der Domain {domain:s} wurde nicht von Let's Encrypt ausgestellt. Es kann nicht automatisch erneuert werden!",
|
"certmanager_attempt_to_renew_nonLE_cert": "Das Zertifikat der Domain {domain:s} wurde nicht von Let's Encrypt ausgestellt. Es kann nicht automatisch erneuert werden!",
|
||||||
"certmanager_attempt_to_renew_valid_cert": "Das Zertifikat der Domain {domain:s} läuft in Kürze ab! Benutze --force um diese Nachricht zu umgehen",
|
"certmanager_attempt_to_renew_valid_cert": "Das Zertifikat der Domain {domain:s} läuft nicht in Kürze ab! (Benutze --force um diese Nachricht zu umgehen)",
|
||||||
"certmanager_domain_http_not_working": "Es scheint so, dass die Domain {domain:s} nicht über HTTP erreicht werden kann. Bitte überprüfe, ob deine DNS und nginx Konfiguration in Ordnung ist",
|
"certmanager_domain_http_not_working": "Es scheint so, dass die Domain {domain:s} nicht über HTTP erreicht werden kann. Bitte überprüfe, ob deine DNS und nginx Konfiguration in Ordnung ist",
|
||||||
"certmanager_error_no_A_record": "Kein DNS 'A' Eintrag für die Domain {domain:s} gefunden. Dein Domainname muss auf diese Maschine weitergeleitet werden, um ein Let's Encrypt Zertifikat installieren zu können! (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )",
|
"certmanager_error_no_A_record": "Kein DNS 'A' Eintrag für die Domain {domain:s} gefunden. Dein Domainname muss auf diese Maschine weitergeleitet werden, um ein Let's Encrypt Zertifikat installieren zu können! (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )",
|
||||||
"certmanager_domain_dns_ip_differs_from_public_ip": "Der DNS 'A' Eintrag der Domain {domain:s} unterscheidet sich von dieser Server-IP. Wenn du gerade deinen A Eintrag verändert hast, warte bitte etwas, damit die Änderungen wirksam werden (du kannst die DNS Propagation mittels Website überprüfen) (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )",
|
"certmanager_domain_dns_ip_differs_from_public_ip": "Der DNS 'A' Eintrag der Domain {domain:s} unterscheidet sich von dieser Server-IP. Wenn du gerade deinen A Eintrag verändert hast, warte bitte etwas, damit die Änderungen wirksam werden (du kannst die DNS Propagation mittels Website überprüfen) (Wenn du weißt was du tust, kannst du --no-checks benutzen, um diese Überprüfung zu überspringen. )",
|
||||||
"certmanager_domain_not_resolved_locally": "Die Domain {domain:s} konnte von innerhalb des Yunohost-Servers nicht aufgelöst werden. Das kann passieren, wenn du den DNS Eintrag vor Kurzem verändert hast. Falls dies der Fall ist, warte bitte ein paar Stunden, damit die Änderungen wirksam werden. Wenn der Fehler bestehen bleibt, ziehe in Betracht die Domain {domain:s} in /etc/hosts einzutragen. (Wenn du weißt was du tust, benutze --no-checks , um diese Nachricht zu umgehen. )",
|
|
||||||
"certmanager_cannot_read_cert": "Es ist ein Fehler aufgetreten, als es versucht wurde das aktuelle Zertifikat für die Domain {domain:s} zu öffnen (Datei: {file:s}), Grund: {reason:s}",
|
"certmanager_cannot_read_cert": "Es ist ein Fehler aufgetreten, als es versucht wurde das aktuelle Zertifikat für die Domain {domain:s} zu öffnen (Datei: {file:s}), Grund: {reason:s}",
|
||||||
"certmanager_cert_install_success_selfsigned": "Ein selbstsigniertes Zertifikat für die Domain {domain:s} wurde erfolgreich installiert!",
|
"certmanager_cert_install_success_selfsigned": "Ein selbstsigniertes Zertifikat für die Domain {domain:s} wurde erfolgreich installiert!",
|
||||||
"certmanager_cert_install_success": "Für die Domain {domain:s} wurde erfolgreich ein Let's Encrypt installiert!",
|
"certmanager_cert_install_success": "Für die Domain {domain:s} wurde erfolgreich ein Let's Encrypt installiert!",
|
||||||
"certmanager_cert_renew_success": "Das Let's Encrypt Zertifikat für die Domain {domain:s} wurde erfolgreich erneuert!",
|
"certmanager_cert_renew_success": "Das Let's Encrypt Zertifikat für die Domain {domain:s} wurde erfolgreich erneuert!",
|
||||||
"certmanager_old_letsencrypt_app_detected": "\nYunohost hat erkannt, dass eine Version von 'letsencrypt' installiert ist, die mit den neuen, integrierten Zertifikatsmanagement-Features in Yunohost kollidieren. Wenn du die neuen Features nutzen willst, führe die folgenden Befehle aus:\n\n yunohost app remove letsencrypt\n yunohost domain cert-install\n\nAnm.: Diese Befehle werden die selbstsignierten und Let's Encrypt Zertifikate aller Domains neu installieren",
|
|
||||||
"certmanager_hit_rate_limit": "Es wurden innerhalb kurzer Zeit schon zu viele Zertifikate für die exakt gleiche Domain {domain:s} ausgestellt. Bitte versuche es später nochmal. Besuche https://letsencrypt.org/docs/rate-limits/ für mehr Informationen",
|
"certmanager_hit_rate_limit": "Es wurden innerhalb kurzer Zeit schon zu viele Zertifikate für die exakt gleiche Domain {domain:s} ausgestellt. Bitte versuche es später nochmal. Besuche https://letsencrypt.org/docs/rate-limits/ für mehr Informationen",
|
||||||
"certmanager_cert_signing_failed": "Signieren des neuen Zertifikats ist fehlgeschlagen",
|
"certmanager_cert_signing_failed": "Signieren des neuen Zertifikats ist fehlgeschlagen",
|
||||||
"certmanager_no_cert_file": "Die Zertifikatsdatei für die Domain {domain:s} (Datei: {file:s}) konnte nicht gelesen werden",
|
"certmanager_no_cert_file": "Die Zertifikatsdatei für die Domain {domain:s} (Datei: {file:s}) konnte nicht gelesen werden",
|
||||||
|
@ -272,87 +185,134 @@
|
||||||
"certmanager_self_ca_conf_file_not_found": "Die Konfigurationsdatei der Zertifizierungsstelle für selbstsignierte Zertifikate wurde nicht gefunden (Datei {file:s})",
|
"certmanager_self_ca_conf_file_not_found": "Die Konfigurationsdatei der Zertifizierungsstelle für selbstsignierte Zertifikate wurde nicht gefunden (Datei {file:s})",
|
||||||
"certmanager_acme_not_configured_for_domain": "Das Zertifikat für die Domain {domain:s} scheint nicht richtig installiert zu sein. Bitte führe den Befehl cert-install für diese Domain nochmals aus.",
|
"certmanager_acme_not_configured_for_domain": "Das Zertifikat für die Domain {domain:s} scheint nicht richtig installiert zu sein. Bitte führe den Befehl cert-install für diese Domain nochmals aus.",
|
||||||
"certmanager_unable_to_parse_self_CA_name": "Der Name der Zertifizierungsstelle für selbstsignierte Zertifikate konnte nicht analysiert werden (Datei: {file:s})",
|
"certmanager_unable_to_parse_self_CA_name": "Der Name der Zertifizierungsstelle für selbstsignierte Zertifikate konnte nicht analysiert werden (Datei: {file:s})",
|
||||||
"app_package_need_update": "Es ist notwendig das Paket {app} zu aktualisieren, um Aktualisierungen für YunoHost zu erhalten",
|
|
||||||
"service_regenconf_dry_pending_applying": "Überprüfe ausstehende Konfigurationen, die für den Server {service} notwendig sind...",
|
|
||||||
"service_regenconf_pending_applying": "Überprüfe ausstehende Konfigurationen, die für den Server '{service}' notwendig sind...",
|
|
||||||
"certmanager_http_check_timeout": "Eine Zeitüberschreitung ist aufgetreten als der Server versuchte sich selbst über HTTP mit der öffentlichen IP (Domain {domain:s} mit der IP {ip:s}) zu erreichen. Möglicherweise ist dafür hairpinning oder eine falsch konfigurierte Firewall/Router deines Servers dafür verantwortlich.",
|
"certmanager_http_check_timeout": "Eine Zeitüberschreitung ist aufgetreten als der Server versuchte sich selbst über HTTP mit der öffentlichen IP (Domain {domain:s} mit der IP {ip:s}) zu erreichen. Möglicherweise ist dafür hairpinning oder eine falsch konfigurierte Firewall/Router deines Servers dafür verantwortlich.",
|
||||||
"certmanager_couldnt_fetch_intermediate_cert": "Eine Zeitüberschreitung ist aufgetreten als der Server versuchte die Teilzertifikate von Let's Encrypt zusammenzusetzen. Die Installation/Erneuerung des Zertifikats wurde abgebrochen - bitte versuche es später erneut.",
|
"certmanager_couldnt_fetch_intermediate_cert": "Eine Zeitüberschreitung ist aufgetreten als der Server versuchte die Teilzertifikate von Let's Encrypt zusammenzusetzen. Die Installation/Erneuerung des Zertifikats wurde abgebrochen - bitte versuche es später erneut.",
|
||||||
"appslist_retrieve_bad_format": "Die empfangene Datei der Appliste {appslist:s} ist ungültig",
|
|
||||||
"domain_hostname_failed": "Erstellen des neuen Hostnamens fehlgeschlagen",
|
"domain_hostname_failed": "Erstellen des neuen Hostnamens fehlgeschlagen",
|
||||||
"appslist_name_already_tracked": "Es gibt bereits eine registrierte App-Liste mit Namen {name:s}.",
|
|
||||||
"appslist_url_already_tracked": "Es gibt bereits eine registrierte Anwendungsliste mit dem URL {url:s}.",
|
|
||||||
"appslist_migrating": "Migriere Anwendungsliste {appslist:s} …",
|
|
||||||
"appslist_could_not_migrate": "Konnte Anwendungsliste {appslist:s} nicht migrieren. Konnte die URL nicht verarbeiten... Der alte Cron-Job wurde unter {bkp_file:s} beibehalten.",
|
|
||||||
"appslist_corrupted_json": "Konnte die Anwendungslisten. Es scheint, dass {filename:s} beschädigt ist.",
|
|
||||||
"yunohost_ca_creation_success": "Die lokale Zertifizierungs-Authorität wurde angelegt.",
|
"yunohost_ca_creation_success": "Die lokale Zertifizierungs-Authorität wurde angelegt.",
|
||||||
"app_already_installed_cant_change_url": "Diese Application ist bereits installiert. Die URL kann durch diese Funktion nicht modifiziert werden. Überprüfe ob `app changeurl` verfügbar ist.",
|
"app_already_installed_cant_change_url": "Diese Application ist bereits installiert. Die URL kann durch diese Funktion nicht modifiziert werden. Überprüfe ob `app changeurl` verfügbar ist.",
|
||||||
"app_change_no_change_url_script": "Die Application {app_name:s} unterstützt das anpassen der URL noch nicht. Sie muss gegebenenfalls erweitert werden.",
|
|
||||||
"app_change_url_failed_nginx_reload": "NGINX konnte nicht neu gestartet werden. Hier ist der Output von 'nginx -t':\n{nginx_errors:s}",
|
"app_change_url_failed_nginx_reload": "NGINX konnte nicht neu gestartet werden. Hier ist der Output von 'nginx -t':\n{nginx_errors:s}",
|
||||||
"app_change_url_identical_domains": "Die alte und neue domain/url_path sind identisch: ('{domain:s} {path:s}'). Es gibt nichts zu tun.",
|
"app_change_url_identical_domains": "Die alte und neue domain/url_path sind identisch: ('{domain:s} {path:s}'). Es gibt nichts zu tun.",
|
||||||
"app_already_up_to_date": "{app:s} ist schon aktuell",
|
"app_already_up_to_date": "{app:s} ist bereits aktuell",
|
||||||
"backup_abstract_method": "Diese Backup-Methode wird noch nicht unterstützt",
|
"backup_abstract_method": "Diese Backup-Methode wird noch nicht unterstützt",
|
||||||
"backup_applying_method_tar": "Erstellen des Backup-tar Archives...",
|
"backup_applying_method_tar": "Erstellen des Backup-tar Archives…",
|
||||||
"backup_applying_method_copy": "Kopiere alle Dateien ins Backup…",
|
"backup_applying_method_copy": "Kopiere alle Dateien ins Backup…",
|
||||||
"app_change_url_no_script": "Die Anwendung '{app_name:s}' unterstützt bisher keine URL-Modufikation. Vielleicht gibt es eine Aktualisierung.",
|
"app_change_url_no_script": "Die Anwendung '{app_name:s}' unterstützt bisher keine URL-Modifikation. Vielleicht sollte sie aktualisiert werden.",
|
||||||
"app_location_unavailable": "Diese URL ist entweder nicht verfügbar oder steht in Konflikt mit den bereits installierten Apps:\n{apps: s}",
|
"app_location_unavailable": "Diese URL ist nicht verfügbar oder wird von einer installierten Anwendung genutzt:\n{apps:s}",
|
||||||
"backup_applying_method_custom": "Rufe die benutzerdefinierte Backup-Methode '{method:s}' auf…",
|
"backup_applying_method_custom": "Rufe die benutzerdefinierte Backup-Methode '{method:s}' auf…",
|
||||||
"backup_archive_system_part_not_available": "Der System-Teil '{part:s}' ist in diesem Backup nicht enthalten",
|
"backup_archive_system_part_not_available": "Der System-Teil '{part:s}' ist in diesem Backup nicht enthalten",
|
||||||
"backup_archive_mount_failed": "Das Einbinden des Backup-Archives ist fehlgeschlagen",
|
"backup_archive_writing_error": "Die Dateien '{source:s} (im Ordner '{dest:s}') konnten nicht in das komprimierte Archiv-Backup '{archive:s}' hinzugefügt werden",
|
||||||
"backup_archive_writing_error": "Die Dateien konnten nicht in der komprimierte Archiv-Backup hinzugefügt werden",
|
|
||||||
"app_change_url_success": "{app:s} URL ist nun {domain:s}{path:s}",
|
"app_change_url_success": "{app:s} URL ist nun {domain:s}{path:s}",
|
||||||
"backup_applying_method_borg": "Sende alle Dateien zur Sicherung ins borg-backup repository…",
|
"backup_applying_method_borg": "Sende alle Dateien zur Sicherung ins borg-backup repository…",
|
||||||
"invalid_url_format": "ungültiges URL Format",
|
"global_settings_bad_type_for_setting": "Falscher Typ für Einstellung {setting:s}. Empfangen: {received_type:s}, aber erwartet: {expected_type:s}",
|
||||||
"global_settings_bad_type_for_setting": "Falscher Typ für Einstellung {setting: s}. Empfangen: {receive_type: s}, aber erwartet: {expected_type: s}",
|
"global_settings_bad_choice_for_enum": "Falsche Wahl für die Einstellung {setting:s}. Habe '{choice:s}' erhalten, aber es stehen nur folgende Auswahlmöglichkeiten zur Verfügung: {available_choices:s}",
|
||||||
"global_settings_bad_choice_for_enum": "Falsche Wahl für die Einstellung {setting: s}. Habe '{choice: s}' erhalten, aber es stehen nur folgende Auswahlmöglichkeiten zur Verfügung: {available_choices: s}",
|
"file_does_not_exist": "Die Datei {path:s} existiert nicht.",
|
||||||
"file_does_not_exist": "Die Datei {path: s} existiert nicht.",
|
|
||||||
"experimental_feature": "Warnung: Diese Funktion ist experimentell und gilt nicht als stabil. Sie sollten sie nur verwenden, wenn Sie wissen, was Sie tun.",
|
"experimental_feature": "Warnung: Diese Funktion ist experimentell und gilt nicht als stabil. Sie sollten sie nur verwenden, wenn Sie wissen, was Sie tun.",
|
||||||
"error_when_removing_sftpuser_group": "Fehler beim Versuch, die Gruppe sftpusers zu entfernen",
|
"dyndns_domain_not_provided": "Der DynDNS-Anbieter {provider:s} kann die Domain(s) {domain:s} nicht bereitstellen.",
|
||||||
"edit_permission_with_group_all_users_not_allowed": "Sie dürfen die Berechtigung für die Gruppe \"all_users\" nicht bearbeiten. Verwenden Sie stattdessen \"yunohost user permission clear APP\" oder \"yunohost user permission add APP -u USER\".",
|
"dyndns_could_not_check_available": "Konnte nicht überprüfen, ob {domain:s} auf {provider:s} verfügbar ist.",
|
||||||
"edit_group_not_allowed": "Du bist nicht berechtigt zum Bearbeiten der Gruppe {group: s}",
|
"dyndns_could_not_check_provide": "Konnte nicht überprüft, ob {provider:s} die Domain(s) {domain:s} bereitstellen kann.",
|
||||||
"dyndns_domain_not_provided": "Der Dyndns-Anbieter {provider: s} kann die Domain(s) {domain: s} nicht bereitstellen.",
|
|
||||||
"dyndns_could_not_check_available": "Konnte nicht überprüfen, ob {domain: s} auf {provider: s} verfügbar ist.",
|
|
||||||
"dyndns_could_not_check_provide": "Konnte nicht überprüft, ob {provider: s} die Domain(s) {domain: s} bereitstellen kann.",
|
|
||||||
"domain_dyndns_dynette_is_unreachable": "YunoHost dynette kann nicht erreicht werden, entweder ist Ihr YunoHost nicht korrekt mit dem Internet verbunden oder der dynette-Server ist inaktiv. Fehler: {error}",
|
|
||||||
"domain_dns_conf_is_just_a_recommendation": "Dieser Befehl zeigt Ihnen, was die * empfohlene * Konfiguration ist. Die DNS-Konfiguration wird NICHT für Sie eingerichtet. Es liegt in Ihrer Verantwortung, Ihre DNS-Zone in Ihrem Registrar gemäß dieser Empfehlung zu konfigurieren.",
|
"domain_dns_conf_is_just_a_recommendation": "Dieser Befehl zeigt Ihnen, was die * empfohlene * Konfiguration ist. Die DNS-Konfiguration wird NICHT für Sie eingerichtet. Es liegt in Ihrer Verantwortung, Ihre DNS-Zone in Ihrem Registrar gemäß dieser Empfehlung zu konfigurieren.",
|
||||||
"dpkg_lock_not_available": "Dieser Befehl kann momentan nicht ausgeführt werden, da anscheinend ein anderes Programm die Sperre von dpkg (dem Systempaket-Manager) verwendet",
|
"dpkg_lock_not_available": "Dieser Befehl kann momentan nicht ausgeführt werden, da anscheinend ein anderes Programm die Sperre von dpkg (dem Systempaket-Manager) verwendet",
|
||||||
"confirm_app_install_thirdparty": "WARNUNG! Das Installieren von Anwendungen von Drittanbietern kann die Integrität und Sicherheit Deines Systems beeinträchtigen. Du solltest es wahrscheinlich NICHT installieren, es sei denn, Du weisst, was Du tust. Bist du bereit, dieses Risiko einzugehen? [{answers: s}] ",
|
"confirm_app_install_thirdparty": "WARNUNG! Das Installieren von Anwendungen von Drittanbietern kann die Integrität und Sicherheit Deines Systems beeinträchtigen. Du solltest es wahrscheinlich NICHT installieren, es sei denn, Du weisst, was Du tust. Bist du bereit, dieses Risiko einzugehen? [{answers:s}]",
|
||||||
"confirm_app_install_danger": "WARNUNG! Diese Anwendung ist noch experimentell (wenn nicht ausdrücklich \"not working\"/\"funktioniert nicht\") und es ist wahrscheinlich, dass Dein System Schaden nimmt! Du solltest es wahrscheinlich NICHT installieren, es sei denn, Du weisst, was Du tust. Bist du bereit, dieses Risiko einzugehen? [{answers: s}] ",
|
"confirm_app_install_danger": "WARNUNG! Diese Anwendung ist noch experimentell (wenn nicht ausdrücklich \"not working\"/\"funktioniert nicht\") und es ist wahrscheinlich, dass Dein System Schaden nimmt! Du solltest es wahrscheinlich NICHT installieren, es sei denn, Du weisst, was Du tust. Bist du bereit, dieses Risiko einzugehen? [{answers:s}]",
|
||||||
"confirm_app_install_warning": "Warnung: Diese Anwendung funktioniert möglicherweise, ist jedoch nicht gut in YunoHost integriert. Einige Funktionen wie Single Sign-On und Backup / Restore sind möglicherweise nicht verfügbar. Trotzdem installieren? [{answers: s}] ",
|
"confirm_app_install_warning": "Warnung: Diese Anwendung funktioniert möglicherweise, ist jedoch nicht gut in YunoHost integriert. Einige Funktionen wie Single Sign-On und Backup / Restore sind möglicherweise nicht verfügbar. Trotzdem installieren? [{answers:s}] ",
|
||||||
"backup_with_no_restore_script_for_app": "App {app: s} hat kein Wiederherstellungsskript. Das Backup dieser App kann nicht automatisch wiederhergestellt werden.",
|
"backup_with_no_restore_script_for_app": "Die App {app:s} hat kein Wiederherstellungsskript. Das Backup dieser App kann nicht automatisch wiederhergestellt werden.",
|
||||||
"backup_with_no_backup_script_for_app": "App {app: s} hat kein Sicherungsskript. Ignoriere es.",
|
"backup_with_no_backup_script_for_app": "Die App {app:s} hat kein Sicherungsskript. Ignoriere es.",
|
||||||
"backup_unable_to_organize_files": "Dateien im Archiv können mit der schnellen Methode nicht organisiert werden",
|
"backup_unable_to_organize_files": "Dateien im Archiv konnten nicht mit der schnellen Methode organisiert werden",
|
||||||
"backup_system_part_failed": "Der Systemteil '{part: s}' kann nicht gesichert werden",
|
"backup_system_part_failed": "Der Systemteil '{part:s}' konnte nicht gesichert werden",
|
||||||
"backup_permission": "Sicherungsberechtigung für App {app: s}",
|
"backup_permission": "Sicherungsberechtigung für App {app:s}",
|
||||||
"backup_output_symlink_dir_broken": "Sie haben einen fehlerhaften Symlink anstelle Ihres Archivverzeichnisses '{path: s}'. Möglicherweise haben Sie ein spezielles Setup, um Ihre Daten auf einem anderen Dateisystem zu sichern. In diesem Fall haben Sie wahrscheinlich vergessen, Ihre Festplatte oder Ihren USB-Schlüssel erneut einzuhängen oder anzuschließen.",
|
"backup_output_symlink_dir_broken": "Ihr Archivverzeichnis '{path:s}' ist ein fehlerhafter Symlink. Vielleicht haben Sie vergessen, das Speichermedium, auf das er verweist, neu zu mounten oder einzustecken.",
|
||||||
"backup_mount_archive_for_restore": "Archiv für Wiederherstellung vorbereiten…",
|
"backup_mount_archive_for_restore": "Archiv für Wiederherstellung vorbereiten…",
|
||||||
"backup_method_tar_finished": "Sicherungs-Tar-Archiv erstellt",
|
"backup_method_tar_finished": "Tar-Backup-Archiv erstellt",
|
||||||
"backup_method_custom_finished": "Benutzerdefinierte Sicherungsmethode '{method: s}' beendet",
|
"backup_method_custom_finished": "Benutzerdefinierte Sicherungsmethode '{method:s}' beendet",
|
||||||
"backup_method_copy_finished": "Sicherungskopie beendet",
|
"backup_method_copy_finished": "Sicherungskopie beendet",
|
||||||
"backup_method_borg_finished": "Backup in Borg beendet",
|
"backup_method_borg_finished": "Backup in Borg beendet",
|
||||||
"backup_custom_need_mount_error": "Bei der benutzerdefinierten Sicherungsmethode ist beim Arbeitsschritt \"Braucht ein Einhängen/Verbinden\" (need_mount) ein Fehler aufgetreten",
|
|
||||||
"backup_custom_mount_error": "Bei der benutzerdefinierten Sicherungsmethode ist beim Arbeitsschritt \"Einhängen/Verbinden\" ein Fehler aufgetreten",
|
"backup_custom_mount_error": "Bei der benutzerdefinierten Sicherungsmethode ist beim Arbeitsschritt \"Einhängen/Verbinden\" ein Fehler aufgetreten",
|
||||||
"backup_custom_backup_error": "Bei der benutzerdefinierten Sicherungsmethode ist beim Arbeitsschritt \"Sicherung\" ein Fehler aufgetreten",
|
"backup_custom_backup_error": "Bei der benutzerdefinierten Sicherungsmethode ist beim Arbeitsschritt \"Sicherung\" ein Fehler aufgetreten",
|
||||||
"backup_csv_creation_failed": "Die CSV-Datei, die für zukünftige Wiederherstellungsvorgänge erforderlich ist, kann nicht erstellt werden",
|
"backup_csv_creation_failed": "Die zur Wiederherstellung erforderliche CSV-Datei kann nicht erstellt werden",
|
||||||
"backup_couldnt_bind": "{Src: s} konnte nicht an {dest: s} angebunden werden.",
|
"backup_couldnt_bind": "{src:s} konnte nicht an {dest:s} angebunden werden.",
|
||||||
"backup_borg_not_implemented": "Die Borg-Sicherungsmethode ist noch nicht implementiert",
|
"backup_borg_not_implemented": "Die Borg-Sicherungsmethode ist noch nicht implementiert",
|
||||||
"backup_ask_for_copying_if_needed": "Einige Dateien konnten mit der Methode, die es vermeidet vorübergehend Speicherplatz auf dem System zu verschwenden, nicht gesichert werden. Zur Durchführung der Sicherung sollten vorübergehend {size: s} MB verwendet werden. Sind Sie einverstanden?",
|
"backup_ask_for_copying_if_needed": "Möchten Sie die Sicherung mit {size:s} MB temporär durchführen? (Dieser Weg wird verwendet, da einige Dateien nicht mit einer effizienteren Methode vorbereitet werden konnten).",
|
||||||
"backup_actually_backuping": "Erstelle nun ein Backup-Archiv aus den gesammelten Dateien …",
|
"backup_actually_backuping": "Erstellt ein Backup-Archiv aus den gesammelten Dateien …",
|
||||||
"ask_path": "Pfad",
|
|
||||||
"ask_new_path": "Neuer Pfad",
|
"ask_new_path": "Neuer Pfad",
|
||||||
"ask_new_domain": "Neue Domain",
|
"ask_new_domain": "Neue Domain",
|
||||||
"apps_permission_restoration_failed": "Die Berechtigung '{permission: s}' für die Wiederherstellung der App {app: s} ist fehlgeschlagen",
|
|
||||||
"apps_permission_not_found": "Keine Berechtigung für die installierten Apps gefunden",
|
|
||||||
"app_upgrade_some_app_failed": "Einige Anwendungen können nicht aktualisiert werden",
|
"app_upgrade_some_app_failed": "Einige Anwendungen können nicht aktualisiert werden",
|
||||||
"app_upgrade_app_name": "{App} wird jetzt aktualisiert…",
|
"app_upgrade_app_name": "{app} wird jetzt aktualisiert…",
|
||||||
"app_upgrade_several_apps": "Die folgenden Apps werden aktualisiert: {apps}",
|
"app_upgrade_several_apps": "Die folgenden Apps werden aktualisiert: {apps}",
|
||||||
"app_start_restore": "Anwendung {app} wird wiederhergestellt…",
|
"app_start_restore": "Anwendung {app} wird wiederhergestellt…",
|
||||||
"app_start_backup": "Sammeln von Dateien, die für {app} gesichert werden sollen…",
|
"app_start_backup": "Sammeln von Dateien, die für {app} gesichert werden sollen…",
|
||||||
"app_start_remove": "Anwendung {app} wird entfernt…",
|
"app_start_remove": "Anwendung {app} wird entfernt…",
|
||||||
"app_start_install": "Anwendung {app} wird installiert…",
|
"app_start_install": "Anwendung {app} wird installiert…",
|
||||||
"app_not_upgraded": "Die App '{failed_app}' konnte nicht aktualisiert werden. Infolgedessen wurden die folgenden App-Upgrades abgebrochen: {apps}",
|
"app_not_upgraded": "Die App '{failed_app}' konnte nicht aktualisiert werden. Infolgedessen wurden die folgenden App-Upgrades abgebrochen: {apps}",
|
||||||
"app_make_default_location_already_used": "Die App \"{app}\" kann nicht als Standard für die Domain \"{domain}\" festgelegt werden. Sie wird bereits von der anderen App \"{other_app}\" verwendet",
|
"app_make_default_location_already_used": "Die App \"{app}\" kann nicht als Standard für die Domain \"{domain}\" festgelegt werden. Sie wird bereits von der App \"{other_app}\" verwendet",
|
||||||
"aborting": "Breche ab.",
|
"aborting": "Breche ab.",
|
||||||
"app_action_cannot_be_ran_because_required_services_down": "Diese App erfordert einige Dienste, die derzeit nicht verfügbar sind. Bevor Sie fortfahren, sollten Sie versuchen, die folgenden Dienste neu zu starten (und möglicherweise untersuchen, warum sie nicht verfügbar sind): {services}",
|
"app_action_cannot_be_ran_because_required_services_down": "Diese erforderlichen Dienste sollten zur Durchführung dieser Aktion laufen: {services}. Versuchen Sie, sie neu zu starten, um fortzufahren (und möglicherweise zu untersuchen, warum sie nicht verfügbar sind).",
|
||||||
"already_up_to_date": "Nichts zu tun. Alles ist bereits auf dem neusten Stand.",
|
"already_up_to_date": "Nichts zu tun. Alles ist bereits auf dem neusten Stand.",
|
||||||
"admin_password_too_long": "Bitte ein Passwort kürzer als 127 Zeichen wählen"
|
"admin_password_too_long": "Bitte ein Passwort kürzer als 127 Zeichen wählen",
|
||||||
|
"app_action_broke_system": "Diese Aktion scheint diese wichtigen Dienste unterbrochen zu haben: {services}",
|
||||||
|
"apps_already_up_to_date": "Alle Apps sind bereits aktuell",
|
||||||
|
"backup_copying_to_organize_the_archive": "Kopieren von {size:s} MB, um das Archiv zu organisieren",
|
||||||
|
"global_settings_setting_security_ssh_compatibility": "Kompatibilität vs. Sicherheitskompromiss für den SSH-Server. Beeinflusst die Chiffren (und andere sicherheitsrelevante Aspekte)",
|
||||||
|
"group_deleted": "Gruppe '{group}' gelöscht",
|
||||||
|
"group_deletion_failed": "Kann Gruppe '{group}' nicht löschen",
|
||||||
|
"dyndns_provider_unreachable": "Dyndns-Anbieter {provider} kann nicht erreicht werden: Entweder ist dein YunoHost nicht korrekt mit dem Internet verbunden oder der Dynette-Server ist ausgefallen.",
|
||||||
|
"group_created": "Gruppe '{group}' angelegt",
|
||||||
|
"group_creation_failed": "Kann Gruppe '{group}' nicht anlegen",
|
||||||
|
"group_unknown": "Die Gruppe '{group:s}' ist unbekannt",
|
||||||
|
"group_updated": "Gruppe '{group:s}' erneuert",
|
||||||
|
"group_update_failed": "Kann Gruppe '{group:s}' nicht anpassen",
|
||||||
|
"log_does_exists": "Es gibt kein Operationsprotokoll mit dem Namen'{log}', verwende'yunohost log list', um alle verfügbaren Operationsprotokolle anzuzeigen",
|
||||||
|
"log_operation_unit_unclosed_properly": "Die Operationseinheit wurde nicht richtig geschlossen",
|
||||||
|
"global_settings_setting_security_postfix_compatibility": "Kompatibilität vs. Sicherheitskompromiss für den Postfix-Server. Beeinflusst die Chiffren (und andere sicherheitsrelevante Aspekte)",
|
||||||
|
"log_category_404": "Die Log-Kategorie '{category}' existiert nicht",
|
||||||
|
"global_settings_unknown_type": "Unerwartete Situation, die Einstellung {setting:s} scheint den Typ {unknown_type:s} zu haben, ist aber kein vom System unterstützter Typ.",
|
||||||
|
"dpkg_is_broken": "Du kannst das gerade nicht tun, weil dpkg/APT (der Systempaketmanager) in einem defekten Zustand zu sein scheint.... Du kannst versuchen, dieses Problem zu lösen, indem du dich über SSH verbindest und `sudo dpkg --configure -a` ausführst.",
|
||||||
|
"global_settings_unknown_setting_from_settings_file": "Unbekannter Schlüssel in den Einstellungen: '{setting_key:s}', verwerfen und speichern in /etc/yunohost/settings-unknown.json",
|
||||||
|
"log_link_to_log": "Vollständiges Log dieser Operation: '<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\">{desc}</a>'",
|
||||||
|
"global_settings_setting_example_bool": "Beispiel einer booleschen Option",
|
||||||
|
"log_help_to_get_log": "Um das Protokoll der Operation '{desc}' anzuzeigen, verwende den Befehl 'yunohost log display {name}'",
|
||||||
|
"global_settings_setting_security_nginx_compatibility": "Kompatibilität vs. Sicherheitskompromiss für den Webserver NGINX. Beeinflusst die Chiffren (und andere sicherheitsrelevante Aspekte)",
|
||||||
|
"backup_php5_to_php7_migration_may_fail": "Dein Archiv konnte nicht für PHP 7 konvertiert werden, Du kannst deine PHP-Anwendungen möglicherweise nicht wiederherstellen (Grund: {error:s})",
|
||||||
|
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Erlaubt die Verwendung eines (veralteten) DSA-Hostkeys für die SSH-Daemon-Konfiguration",
|
||||||
|
"global_settings_setting_example_string": "Beispiel einer string Option",
|
||||||
|
"log_app_remove": "Entferne die Anwendung '{}'",
|
||||||
|
"global_settings_setting_example_int": "Beispiel einer int Option",
|
||||||
|
"global_settings_cant_open_settings": "Einstellungsdatei konnte nicht geöffnet werden, Grund: {reason:s}",
|
||||||
|
"global_settings_cant_write_settings": "Einstellungsdatei konnte nicht gespeichert werden, Grund: {reason:s}",
|
||||||
|
"log_app_install": "Installiere die Anwendung '{}'",
|
||||||
|
"global_settings_reset_success": "Frühere Einstellungen werden nun auf {path:s} gesichert",
|
||||||
|
"log_app_upgrade": "Upgrade der Anwendung '{}'",
|
||||||
|
"good_practices_about_admin_password": "Sie sind nun dabei, ein neues Administrationspasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - obwohl es sinnvoll ist, ein längeres Passwort (z.B. eine Passphrase) und/oder eine Variation von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.",
|
||||||
|
"log_corrupted_md_file": "Die mit Protokollen verknüpfte YAML-Metadatendatei ist beschädigt: '{md_file}\nFehler: {error}''",
|
||||||
|
"global_settings_cant_serialize_settings": "Einstellungsdaten konnten nicht serialisiert werden, Grund: {reason:s}",
|
||||||
|
"log_help_to_get_failed_log": "Der Vorgang'{desc}' konnte nicht abgeschlossen werden. Bitte teile das vollständige Protokoll dieser Operation mit dem Befehl 'yunohost log display {name} --share', um Hilfe zu erhalten",
|
||||||
|
"backup_no_uncompress_archive_dir": "Dieses unkomprimierte Archivverzeichnis gibt es nicht",
|
||||||
|
"log_app_change_url": "Ändere die URL der Anwendung '{}'",
|
||||||
|
"global_settings_setting_security_password_user_strength": "Stärke des Benutzerpassworts",
|
||||||
|
"good_practices_about_user_password": "Du bist nun dabei, ein neues Benutzerpasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - obwohl es ratsam ist, ein längeres Passwort (z.B. eine Passphrase) und/oder eine Variation von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.",
|
||||||
|
"global_settings_setting_example_enum": "Beispiel einer enum Option",
|
||||||
|
"log_link_to_failed_log": "Der Vorgang konnte nicht abgeschlossen werden '{desc}'. Bitte gib das vollständige Protokoll dieser Operation mit <a href=\"#/tools/logs/{name}\">Klicken Sie hier</a> an, um Hilfe zu erhalten",
|
||||||
|
"backup_cant_mount_uncompress_archive": "Das unkomprimierte Archiv konnte nicht als schreibgeschützt gemountet werden",
|
||||||
|
"backup_csv_addition_failed": "Es konnten keine Dateien zur Sicherung in die CSV-Datei hinzugefügt werden",
|
||||||
|
"global_settings_setting_security_password_admin_strength": "Stärke des Admin-Passworts",
|
||||||
|
"global_settings_key_doesnt_exists": "Der Schlüssel'{settings_key:s}' existiert nicht in den globalen Einstellungen, du kannst alle verfügbaren Schlüssel sehen, indem du 'yunohost settings list' ausführst",
|
||||||
|
"log_app_makedefault": "Mache '{}' zur Standard-Anwendung",
|
||||||
|
"hook_json_return_error": "Konnte die Rückkehr vom Einsprungpunkt {path:s} nicht lesen. Fehler: {msg:s}. Unformatierter Inhalt: {raw_content}",
|
||||||
|
"app_full_domain_unavailable": "Es tut uns leid, aber diese Anwendung erfordert die Installation auf einer eigenen Domain, aber einige andere Anwendungen sind bereits auf der Domäne'{domain}' installiert. Eine mögliche Lösung ist das Hinzufügen und Verwenden einer Subdomain, die dieser Anwendung zugeordnet ist.",
|
||||||
|
"app_install_failed": "Installation von {app} fehlgeschlagen: {error}",
|
||||||
|
"app_install_script_failed": "Im Installationsscript ist ein Fehler aufgetreten",
|
||||||
|
"app_remove_after_failed_install": "Entfernen der App nach fehlgeschlagener Installation…",
|
||||||
|
"app_upgrade_script_failed": "Es ist ein Fehler im App-Upgrade-Skript aufgetreten",
|
||||||
|
"diagnosis_basesystem_host": "Server läuft unter Debian {debian_version}.",
|
||||||
|
"diagnosis_basesystem_kernel": "Server läuft unter Linux-Kernel {kernel_version}",
|
||||||
|
"diagnosis_basesystem_ynh_single_version": "{package} Version: {version} ({repo})",
|
||||||
|
"diagnosis_basesystem_ynh_main_version": "Server läuft YunoHost {main_version} ({repo})",
|
||||||
|
"diagnosis_basesystem_ynh_inconsistent_versions": "Sie verwenden inkonsistente Versionen der YunoHost-Pakete... wahrscheinlich wegen eines fehlgeschlagenen oder teilweisen Upgrades.",
|
||||||
|
"diagnosis_display_tip_web": "Sie können den Abschnitt Diagnose (im Startbildschirm) aufrufen, um die gefundenen Probleme anzuzeigen.",
|
||||||
|
"apps_catalog_init_success": "Apps-Katalogsystem initialisiert!",
|
||||||
|
"apps_catalog_updating": "Aktualisierung des Applikationskatalogs...",
|
||||||
|
"apps_catalog_failed_to_download": "Der {apps_catalog} Apps-Katalog kann nicht heruntergeladen werden: {error}",
|
||||||
|
"apps_catalog_obsolete_cache": "Der Cache des Apps-Katalogs ist leer oder veraltet.",
|
||||||
|
"apps_catalog_update_success": "Der Apps-Katalog wurde aktualisiert!",
|
||||||
|
"password_too_simple_1": "Das Passwort muss mindestens 8 Zeichen lang sein",
|
||||||
|
"diagnosis_display_tip_cli": "Sie können 'yunohost diagnosis show --issues' ausführen, um die gefundenen Probleme anzuzeigen."
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
{}
|
{
|
||||||
|
"password_too_simple_1": "Ο κωδικός πρόσβασης πρέπει να έχει μήκος τουλάχιστον 8 χαρακτήρων"
|
||||||
|
}
|
457
locales/en.json
457
locales/en.json
|
@ -3,76 +3,65 @@
|
||||||
"action_invalid": "Invalid action '{action:s}'",
|
"action_invalid": "Invalid action '{action:s}'",
|
||||||
"admin_password": "Administration password",
|
"admin_password": "Administration password",
|
||||||
"admin_password_change_failed": "Cannot change password",
|
"admin_password_change_failed": "Cannot change password",
|
||||||
"admin_password_changed": "The administration password got changed",
|
"admin_password_changed": "The administration password was changed",
|
||||||
"admin_password_too_long": "Please choose a password shorter than 127 characters",
|
"admin_password_too_long": "Please choose a password shorter than 127 characters",
|
||||||
"already_up_to_date": "Nothing to do. Everything is already up-to-date.",
|
"already_up_to_date": "Nothing to do. Everything is already up-to-date.",
|
||||||
"app_action_cannot_be_ran_because_required_services_down": "This app requires some services which are currently down. Before continuing, you should try to restart the following services (and possibly investigate why they are down): {services}",
|
"app_action_cannot_be_ran_because_required_services_down": "These required services should be running to run this action: {services}. Try restarting them to continue (and possibly investigate why they are down).",
|
||||||
"app_action_broke_system": "This action seem to have broke these important services: {services}",
|
"app_action_broke_system": "This action seems to have broken these important services: {services}",
|
||||||
"app_already_installed": "{app:s} is already installed",
|
"app_already_installed": "{app:s} is already installed",
|
||||||
"app_already_installed_cant_change_url": "This app is already installed. The URL cannot be changed just by this function. Look into `app changeurl` if it's available.",
|
"app_already_installed_cant_change_url": "This app is already installed. The URL cannot be changed just by this function. Check in `app changeurl` if it's available.",
|
||||||
"app_already_up_to_date": "{app:s} is already up-to-date",
|
"app_already_up_to_date": "{app:s} is already up-to-date",
|
||||||
"app_argument_choice_invalid": "Use one of these choices '{choices:s}' for the argument '{name:s}'",
|
"app_argument_choice_invalid": "Use one of these choices '{choices:s}' for the argument '{name:s}'",
|
||||||
"app_argument_invalid": "Pick a valid value for the argument '{name:s}': {error:s}",
|
"app_argument_invalid": "Pick a valid value for the argument '{name:s}': {error:s}",
|
||||||
"app_argument_required": "Argument '{name:s}' is required",
|
"app_argument_required": "Argument '{name:s}' is required",
|
||||||
"app_change_url_failed_nginx_reload": "Could not reload NGINX. Here is the output of 'nginx -t':\n{nginx_errors:s}",
|
"app_change_url_failed_nginx_reload": "Could not reload NGINX. Here is the output of 'nginx -t':\n{nginx_errors:s}",
|
||||||
"app_change_url_identical_domains": "The old and new domain/url_path are identical ('{domain:s}{path:s}'), nothing to do.",
|
"app_change_url_identical_domains": "The old and new domain/url_path are identical ('{domain:s}{path:s}'), nothing to do.",
|
||||||
"app_change_url_no_script": "This application '{app_name:s}' doesn't support URL modification yet. Maybe you should upgrade it.",
|
"app_change_url_no_script": "The app '{app_name:s}' doesn't support URL modification yet. Maybe you should upgrade it.",
|
||||||
"app_change_url_success": "{app:s} URL is now {domain:s}{path:s}",
|
"app_change_url_success": "{app:s} URL is now {domain:s}{path:s}",
|
||||||
"app_extraction_failed": "Could not extract the installation files",
|
"app_extraction_failed": "Could not extract the installation files",
|
||||||
|
"app_full_domain_unavailable": "Sorry, this app must be installed on a domain of its own, but other apps are already installed on the domain '{domain}'. You could use a subdomain dedicated to this app instead.",
|
||||||
"app_id_invalid": "Invalid app ID",
|
"app_id_invalid": "Invalid app ID",
|
||||||
"app_incompatible": "The app {app} is incompatible with your YunoHost version",
|
|
||||||
"app_install_files_invalid": "These files cannot be installed",
|
"app_install_files_invalid": "These files cannot be installed",
|
||||||
"app_location_already_used": "The app '{app}' is already installed in ({path})",
|
"app_install_failed": "Could not install {app}: {error}",
|
||||||
"app_make_default_location_already_used": "Can't make the app '{app}' the default on the domain, {domain} is already in use by the other app '{other_app}'",
|
"app_install_script_failed": "An error occurred inside the app installation script",
|
||||||
"app_location_install_failed": "Cannot install the app there because it conflicts with the app '{other_app}' already installed in '{other_path}'",
|
"app_make_default_location_already_used": "Can't make the app '{app}' the default on the domain, '{domain}' is already in use by the other app '{other_app}'",
|
||||||
"app_location_unavailable": "This URL is either unavailable, or conflicts with the already installed app(s):\n{apps:s}",
|
"app_location_unavailable": "This URL is either unavailable, or conflicts with the already installed app(s):\n{apps:s}",
|
||||||
"app_manifest_invalid": "Something is wrong with the app manifest: {error}",
|
"app_manifest_invalid": "Something is wrong with the app manifest: {error}",
|
||||||
"app_not_upgraded": "The app '{failed_app}' failed to upgrade, and as a consequence the following apps upgrades have been cancelled: {apps}",
|
"app_not_upgraded": "The app '{failed_app}' failed to upgrade, and as a consequence the following apps' upgrades have been cancelled: {apps}",
|
||||||
"app_upgrade_stopped": "The upgrade of all applications has been stopped to prevent possible damage because the previous application failed to upgrade",
|
|
||||||
"app_not_correctly_installed": "{app:s} seems to be incorrectly installed",
|
"app_not_correctly_installed": "{app:s} seems to be incorrectly installed",
|
||||||
"app_not_installed": "Could not find the application '{app:s}' in the list of installed apps: {all_apps}",
|
"app_not_installed": "Could not find the app '{app:s}' in the list of installed apps: {all_apps}",
|
||||||
"app_not_properly_removed": "{app:s} has not been properly removed",
|
"app_not_properly_removed": "{app:s} has not been properly removed",
|
||||||
"app_package_need_update": "The app {app} package needs to be updated to follow YunoHost changes",
|
|
||||||
"app_removed": "{app:s} removed",
|
"app_removed": "{app:s} removed",
|
||||||
"app_requirements_checking": "Checking required packages for {app}…",
|
"app_requirements_checking": "Checking required packages for {app}…",
|
||||||
"app_requirements_failed": "Some requirements are not met for {app}: {error}",
|
|
||||||
"app_requirements_unmeet": "Requirements are not met for {app}, the package {pkgname} ({version}) must be {spec}",
|
"app_requirements_unmeet": "Requirements are not met for {app}, the package {pkgname} ({version}) must be {spec}",
|
||||||
|
"app_remove_after_failed_install": "Removing the app following the installation failure…",
|
||||||
"app_sources_fetch_failed": "Could not fetch sources files, is the URL correct?",
|
"app_sources_fetch_failed": "Could not fetch sources files, is the URL correct?",
|
||||||
"app_start_install": "Installing application {app}…",
|
"app_start_install": "Installing the app '{app}'…",
|
||||||
"app_start_remove": "Removing application {app}…",
|
"app_start_remove": "Removing the app '{app}'…",
|
||||||
"app_start_backup": "Collecting files to be backed up for {app}…",
|
"app_start_backup": "Collecting files to be backed up for the app '{app}'…",
|
||||||
"app_start_restore": "Restoring application {app}…",
|
"app_start_restore": "Restoring the app '{app}'…",
|
||||||
"app_unknown": "Unknown app",
|
"app_unknown": "Unknown app",
|
||||||
"app_unsupported_remote_type": "Unsupported remote type used for the app",
|
"app_unsupported_remote_type": "Unsupported remote type used for the app",
|
||||||
"app_upgrade_several_apps": "The following apps will be upgraded: {apps}",
|
"app_upgrade_several_apps": "The following apps will be upgraded: {apps}",
|
||||||
"app_upgrade_app_name": "Now upgrading {app}…",
|
"app_upgrade_app_name": "Now upgrading {app}…",
|
||||||
"app_upgrade_failed": "Could not upgrade {app:s}",
|
"app_upgrade_failed": "Could not upgrade {app:s}: {error}",
|
||||||
"app_upgrade_some_app_failed": "Some applications could not be upgraded",
|
"app_upgrade_script_failed": "An error occurred inside the app upgrade script",
|
||||||
|
"app_upgrade_some_app_failed": "Some apps could not be upgraded",
|
||||||
"app_upgraded": "{app:s} upgraded",
|
"app_upgraded": "{app:s} upgraded",
|
||||||
"apps_already_up_to_date": "All applications are already up-to-date",
|
"apps_already_up_to_date": "All apps are already up-to-date",
|
||||||
"apps_permission_not_found": "No permission found for the installed apps",
|
"apps_catalog_init_success": "App catalog system initialized!",
|
||||||
"apps_permission_restoration_failed": "Grant the permission permission '{permission:s}' to restore {app:s}",
|
"apps_catalog_updating": "Updating application catalog…",
|
||||||
"appslist_corrupted_json": "Could not load the application lists. It looks like {filename:s} is damaged.",
|
"apps_catalog_failed_to_download": "Unable to download the {apps_catalog} app catalog: {error}",
|
||||||
"appslist_could_not_migrate": "Could not migrate the app list {appslist:s}! Could not parse the URL… The old cron job was kept kept in {bkp_file:s}.",
|
"apps_catalog_obsolete_cache": "The app catalog cache is empty or obsolete.",
|
||||||
"appslist_fetched": "Updated application list {appslist:s} fetched",
|
"apps_catalog_update_success": "The application catalog has been updated!",
|
||||||
"appslist_migrating": "Migrating application list {appslist:s}…",
|
|
||||||
"appslist_name_already_tracked": "A registered application list with name {name:s} already exists.",
|
|
||||||
"appslist_removed": "{appslist:s} application list removed",
|
|
||||||
"appslist_retrieve_bad_format": "Could not read the fetched application list {appslist:s}",
|
|
||||||
"appslist_retrieve_error": "Cannot retrieve the remote application list {appslist:s}: {error:s}",
|
|
||||||
"appslist_unknown": "Application list {appslist:s} unknown.",
|
|
||||||
"appslist_url_already_tracked": "There is already a registered application list with the URL {url:s}.",
|
|
||||||
"ask_current_admin_password": "Current administration password",
|
|
||||||
"ask_email": "E-mail address",
|
"ask_email": "E-mail address",
|
||||||
"ask_firstname": "First name",
|
"ask_firstname": "First name",
|
||||||
"ask_lastname": "Last name",
|
"ask_lastname": "Last name",
|
||||||
"ask_list_to_remove": "List to remove",
|
|
||||||
"ask_main_domain": "Main domain",
|
"ask_main_domain": "Main domain",
|
||||||
"ask_new_admin_password": "New administration password",
|
"ask_new_admin_password": "New administration password",
|
||||||
"ask_new_domain": "New domain",
|
"ask_new_domain": "New domain",
|
||||||
"ask_new_path": "New path",
|
"ask_new_path": "New path",
|
||||||
"ask_password": "Password",
|
"ask_password": "Password",
|
||||||
"ask_path": "Path",
|
|
||||||
"backup_abstract_method": "This backup method has yet to be implemented",
|
"backup_abstract_method": "This backup method has yet to be implemented",
|
||||||
"backup_actually_backuping": "Creating a backup archive from the collected files…",
|
"backup_actually_backuping": "Creating a backup archive from the collected files…",
|
||||||
"backup_app_failed": "Could not back up the app '{app:s}'",
|
"backup_app_failed": "Could not back up the app '{app:s}'",
|
||||||
|
@ -85,12 +74,14 @@
|
||||||
"backup_archive_name_exists": "A backup archive with this name already exists.",
|
"backup_archive_name_exists": "A backup archive with this name already exists.",
|
||||||
"backup_archive_name_unknown": "Unknown local backup archive named '{name:s}'",
|
"backup_archive_name_unknown": "Unknown local backup archive named '{name:s}'",
|
||||||
"backup_archive_open_failed": "Could not open the backup archive",
|
"backup_archive_open_failed": "Could not open the backup archive",
|
||||||
|
"backup_archive_cant_retrieve_info_json": "Could not load infos for archive '{archive}' ... The info.json cannot be retrieved (or is not a valid json).",
|
||||||
|
"backup_archive_corrupted": "It looks like the backup archive '{archive}' is corrupted : {error}",
|
||||||
"backup_archive_system_part_not_available": "System part '{part:s}' unavailable in this backup",
|
"backup_archive_system_part_not_available": "System part '{part:s}' unavailable in this backup",
|
||||||
"backup_archive_writing_error": "Could not add the files '{source:s}' (named in the archive '{dest:s}') to be backed up into the compressed archive '{archive:s}'",
|
"backup_archive_writing_error": "Could not add the files '{source:s}' (named in the archive '{dest:s}') to be backed up into the compressed archive '{archive:s}'",
|
||||||
"backup_ask_for_copying_if_needed": "Some files could not be prepared for backup using the method that avoids temporarily wasting space on the system. To perform the backup, {size:s}MB will be temporarily. Do you agree?",
|
"backup_ask_for_copying_if_needed": "Do you want to perform the backup using {size:s} MB temporarily? (This way is used since some files could not be prepared using a more efficient method.)",
|
||||||
"backup_borg_not_implemented": "The Borg backup method is not yet implemented",
|
"backup_borg_not_implemented": "The Borg backup method is not yet implemented",
|
||||||
"backup_cant_mount_uncompress_archive": "Could not mount the uncompressed archive as write protected",
|
"backup_cant_mount_uncompress_archive": "Could not mount the uncompressed archive as write protected",
|
||||||
"backup_cleaning_failed": "Could not clean-up the temporary backup folder",
|
"backup_cleaning_failed": "Could not clean up the temporary backup folder",
|
||||||
"backup_copying_to_organize_the_archive": "Copying {size:s}MB to organize the archive",
|
"backup_copying_to_organize_the_archive": "Copying {size:s}MB to organize the archive",
|
||||||
"backup_couldnt_bind": "Could not bind {src:s} to {dest:s}.",
|
"backup_couldnt_bind": "Could not bind {src:s} to {dest:s}.",
|
||||||
"backup_created": "Backup created",
|
"backup_created": "Backup created",
|
||||||
|
@ -102,7 +93,6 @@
|
||||||
"backup_delete_error": "Could not delete '{path:s}'",
|
"backup_delete_error": "Could not delete '{path:s}'",
|
||||||
"backup_deleted": "Backup deleted",
|
"backup_deleted": "Backup deleted",
|
||||||
"backup_hook_unknown": "The backup hook '{hook:s}' is unknown",
|
"backup_hook_unknown": "The backup hook '{hook:s}' is unknown",
|
||||||
"backup_invalid_archive": "This is not a backup archive",
|
|
||||||
"backup_method_borg_finished": "Backup into Borg finished",
|
"backup_method_borg_finished": "Backup into Borg finished",
|
||||||
"backup_method_copy_finished": "Backup copy finalized",
|
"backup_method_copy_finished": "Backup copy finalized",
|
||||||
"backup_method_custom_finished": "Custom backup method '{method:s}' finished",
|
"backup_method_custom_finished": "Custom backup method '{method:s}' finished",
|
||||||
|
@ -110,10 +100,10 @@
|
||||||
"backup_mount_archive_for_restore": "Preparing archive for restoration…",
|
"backup_mount_archive_for_restore": "Preparing archive for restoration…",
|
||||||
"backup_no_uncompress_archive_dir": "There is no such uncompressed archive directory",
|
"backup_no_uncompress_archive_dir": "There is no such uncompressed archive directory",
|
||||||
"backup_nothings_done": "Nothing to save",
|
"backup_nothings_done": "Nothing to save",
|
||||||
"backup_output_directory_forbidden": "Pick a different output directory. Backups can not be created in /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var or /home/yunohost.backup/archives sub-folders",
|
"backup_output_directory_forbidden": "Pick a different output directory. Backups cannot be created in /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var or /home/yunohost.backup/archives sub-folders",
|
||||||
"backup_output_directory_not_empty": "You should pick an empty output directory",
|
"backup_output_directory_not_empty": "You should pick an empty output directory",
|
||||||
"backup_output_directory_required": "You must provide an output directory for the backup",
|
"backup_output_directory_required": "You must provide an output directory for the backup",
|
||||||
"backup_output_symlink_dir_broken": "You have a broken symlink in place of your archive directory '{path:s}'. You may have a specific setup to backup your data on another filesystem, in this case you probably forgot to remount or plug in your hard-drive or USB key.",
|
"backup_output_symlink_dir_broken": "Your archive directory '{path:s}' is a broken symlink. Maybe you forgot to re/mount or plug in the storage medium it points to.",
|
||||||
"backup_permission": "Backup permission for app {app:s}",
|
"backup_permission": "Backup permission for app {app:s}",
|
||||||
"backup_php5_to_php7_migration_may_fail": "Could not convert your archive to support PHP 7, you may be unable to restore your PHP apps (reason: {error:s})",
|
"backup_php5_to_php7_migration_may_fail": "Could not convert your archive to support PHP 7, you may be unable to restore your PHP apps (reason: {error:s})",
|
||||||
"backup_running_hooks": "Running backup hooks…",
|
"backup_running_hooks": "Running backup hooks…",
|
||||||
|
@ -121,7 +111,7 @@
|
||||||
"backup_unable_to_organize_files": "Could not use the quick method to organize files in the archive",
|
"backup_unable_to_organize_files": "Could not use the quick method to organize files in the archive",
|
||||||
"backup_with_no_backup_script_for_app": "The app '{app:s}' has no backup script. Ignoring.",
|
"backup_with_no_backup_script_for_app": "The app '{app:s}' has no backup script. Ignoring.",
|
||||||
"backup_with_no_restore_script_for_app": "The '{app:s}' has no restoration script, you will not be able to automatically restore the backup of this app.",
|
"backup_with_no_restore_script_for_app": "The '{app:s}' has no restoration script, you will not be able to automatically restore the backup of this app.",
|
||||||
"certmanager_acme_not_configured_for_domain": "Certificate for the domain '{domain:s}' does not appear to be correctly installed. Please run 'cert-install' for this domain first.",
|
"certmanager_acme_not_configured_for_domain": "The ACME challenge cannot be ran for {domain} right now because its nginx conf lacks the corresponding code snippet... Please make sure that your nginx configuration is up to date using `yunohost tools regen-conf nginx --dry-run --with-diff`.",
|
||||||
"certmanager_attempt_to_renew_nonLE_cert": "The certificate for the domain '{domain:s}' is not issued by Let's Encrypt. Cannot renew it automatically!",
|
"certmanager_attempt_to_renew_nonLE_cert": "The certificate for the domain '{domain:s}' is not issued by Let's Encrypt. Cannot renew it automatically!",
|
||||||
"certmanager_attempt_to_renew_valid_cert": "The certificate for the domain '{domain:s}' is not about to expire! (You may use --force if you know what you're doing)",
|
"certmanager_attempt_to_renew_valid_cert": "The certificate for the domain '{domain:s}' is not about to expire! (You may use --force if you know what you're doing)",
|
||||||
"certmanager_attempt_to_replace_valid_cert": "You are attempting to overwrite a good and valid certificate for domain {domain:s}! (Use --force to bypass)",
|
"certmanager_attempt_to_replace_valid_cert": "You are attempting to overwrite a good and valid certificate for domain {domain:s}! (Use --force to bypass)",
|
||||||
|
@ -131,36 +121,143 @@
|
||||||
"certmanager_cert_renew_success": "Let's Encrypt certificate renewed for the domain '{domain:s}'",
|
"certmanager_cert_renew_success": "Let's Encrypt certificate renewed for the domain '{domain:s}'",
|
||||||
"certmanager_cert_signing_failed": "Could not sign the new certificate",
|
"certmanager_cert_signing_failed": "Could not sign the new certificate",
|
||||||
"certmanager_certificate_fetching_or_enabling_failed": "Trying to use the new certificate for {domain:s} did not work…",
|
"certmanager_certificate_fetching_or_enabling_failed": "Trying to use the new certificate for {domain:s} did not work…",
|
||||||
"certmanager_conflicting_nginx_file": "Could not prepare domain for ACME challenge: the NGINX configuration file {filepath:s} is conflicting and should be removed first",
|
|
||||||
"certmanager_couldnt_fetch_intermediate_cert": "Timed out when trying to fetch intermediate certificate from Let's Encrypt. Certificate installation/renewal aborted—please try again later.",
|
"certmanager_couldnt_fetch_intermediate_cert": "Timed out when trying to fetch intermediate certificate from Let's Encrypt. Certificate installation/renewal aborted—please try again later.",
|
||||||
"certmanager_domain_cert_not_selfsigned": "The certificate for domain {domain:s} is not self-signed. Are you sure you want to replace it? (Use '--force' to do so.)",
|
"certmanager_domain_cert_not_selfsigned": "The certificate for domain {domain:s} is not self-signed. Are you sure you want to replace it? (Use '--force' to do so.)",
|
||||||
"certmanager_domain_dns_ip_differs_from_public_ip": "The DNS 'A' record for the domain '{domain:s}' is different from this server IP. If you recently modified your A record, please wait for it to propagate (some DNS propagation checkers are available online). (If you know what you are doing, use '--no-checks' to turn off those checks.)",
|
"certmanager_domain_dns_ip_differs_from_public_ip": "The DNS 'A' record for the domain '{domain:s}' is different from this server's IP. If you recently modified your A record, please wait for it to propagate (some DNS propagation checkers are available online). (If you know what you are doing, use '--no-checks' to turn off those checks.)",
|
||||||
"certmanager_domain_http_not_working": "It seems the domain {domain:s} cannot be accessed through HTTP. Check that your DNS and NGINX configuration is correct",
|
"certmanager_domain_http_not_working": "It seems the domain {domain:s} cannot be accessed through HTTP. Check that your DNS and NGINX configuration is correct",
|
||||||
"certmanager_domain_unknown": "Unknown domain '{domain:s}'",
|
"certmanager_domain_unknown": "Unknown domain '{domain:s}'",
|
||||||
"certmanager_error_no_A_record": "No DNS 'A' record found for '{domain:s}'. You need to make your domain name point to your machine to be able to install a Let's Encrypt certificate. (If you know what you are doing, use '--no-checks' to turn off those checks.)",
|
"certmanager_error_no_A_record": "No DNS 'A' record found for '{domain:s}'. You need to make your domain name point to your machine to be able to install a Let's Encrypt certificate. (If you know what you are doing, use '--no-checks' to turn off those checks.)",
|
||||||
|
"certmanager_warning_subdomain_dns_record": "Subdomain '{subdomain:s}' does not resolve to the same IP address as '{domain:s}'. Some features will not be available until you fix this and regenerate the certificate.",
|
||||||
"certmanager_hit_rate_limit": "Too many certificates already issued for this exact set of domains {domain:s} recently. Please try again later. See https://letsencrypt.org/docs/rate-limits/ for more details",
|
"certmanager_hit_rate_limit": "Too many certificates already issued for this exact set of domains {domain:s} recently. Please try again later. See https://letsencrypt.org/docs/rate-limits/ for more details",
|
||||||
"certmanager_http_check_timeout": "Timed out when server tried to contact itself through HTTP using a public IP address (domain '{domain:s}' with IP '{ip:s}'). You may be experiencing a hairpinning issue, or the firewall/router ahead of your server is misconfigured.",
|
"certmanager_http_check_timeout": "Timed out when server tried to contact itself through HTTP using a public IP address (domain '{domain:s}' with IP '{ip:s}'). You may be experiencing a hairpinning issue, or the firewall/router ahead of your server is misconfigured.",
|
||||||
"certmanager_no_cert_file": "Could not read the certificate file for the domain {domain:s} (file: {file:s})",
|
"certmanager_no_cert_file": "Could not read the certificate file for the domain {domain:s} (file: {file:s})",
|
||||||
"certmanager_self_ca_conf_file_not_found": "Could not find configuration file for self-signing authority (file: {file:s})",
|
"certmanager_self_ca_conf_file_not_found": "Could not find configuration file for self-signing authority (file: {file:s})",
|
||||||
"certmanager_unable_to_parse_self_CA_name": "Could not parse name of self-signing authority (file: {file:s})",
|
"certmanager_unable_to_parse_self_CA_name": "Could not parse name of self-signing authority (file: {file:s})",
|
||||||
"confirm_app_install_warning": "Warning: This application may work, but is not well-integrated in YunoHost. Some features such as single sign-on and backup/restore might not be available. Install anyway? [{answers:s}] ",
|
"confirm_app_install_warning": "Warning: This app may work, but is not well-integrated in YunoHost. Some features such as single sign-on and backup/restore might not be available. Install anyway? [{answers:s}] ",
|
||||||
"confirm_app_install_danger": "WARNING! This application is still experimental (if not explicitly not working) and it is likely to break your system! You should probably NOT install it unless you know what you are doing. Are you willing to take that risk? [{answers:s}] ",
|
"confirm_app_install_danger": "DANGER! This app is known to be still experimental (if not explicitly not working)! You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system… If you are willing to take that risk anyway, type '{answers:s}'",
|
||||||
"confirm_app_install_thirdparty": "WARNING! Installing third-party applications may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. Are you willing to take that risk? [{answers:s}] ",
|
"confirm_app_install_thirdparty": "DANGER! This app is not part of Yunohost's app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system… If you are willing to take that risk anyway, type '{answers:s}'",
|
||||||
"custom_app_url_required": "You must provide a URL to upgrade your custom app {app:s}",
|
"custom_app_url_required": "You must provide a URL to upgrade your custom app {app:s}",
|
||||||
"custom_appslist_name_required": "You must provide a name for your custom app list",
|
"diagnosis_basesystem_hardware": "Server hardware architecture is {virt} {arch}",
|
||||||
"diagnosis_debian_version_error": "Could not retrieve the Debian version: {error}",
|
"diagnosis_basesystem_hardware_board": "Server board model is {model}",
|
||||||
"diagnosis_kernel_version_error": "Could not retrieve kernel version: {error}",
|
"diagnosis_basesystem_host": "Server is running Debian {debian_version}",
|
||||||
"diagnosis_monitor_disk_error": "Could not monitor disks: {error}",
|
"diagnosis_basesystem_kernel": "Server is running Linux kernel {kernel_version}",
|
||||||
"diagnosis_monitor_system_error": "Could not monitor system: {error}",
|
"diagnosis_basesystem_ynh_single_version": "{package} version: {version} ({repo})",
|
||||||
"diagnosis_no_apps": "No installed application",
|
"diagnosis_basesystem_ynh_main_version": "Server is running YunoHost {main_version} ({repo})",
|
||||||
"dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state… You can try to solve this issue by connecting through SSH and running `sudo dpkg --configure -a`.",
|
"diagnosis_basesystem_ynh_inconsistent_versions": "You are running inconsistent versions of the YunoHost packages... most probably because of a failed or partial upgrade.",
|
||||||
"dpkg_lock_not_available": "This command can't be ran right now because another program seems to be using the lock of dpkg (the system package manager)",
|
"diagnosis_display_tip": "To see the issues found, you can go to the Diagnosis section of the webadmin, or run 'yunohost diagnosis show --issues' from the command-line.",
|
||||||
"domain_cannot_remove_main": "Cannot remove main domain. Set one first",
|
"diagnosis_failed_for_category": "Diagnosis failed for category '{category}': {error}",
|
||||||
|
"diagnosis_cache_still_valid": "(Cache still valid for {category} diagnosis. Won't re-diagnose it yet!)",
|
||||||
|
"diagnosis_cant_run_because_of_dep": "Can't run diagnosis for {category} while there are important issues related to {dep}.",
|
||||||
|
"diagnosis_ignored_issues": "(+ {nb_ignored} ignored issue(s))",
|
||||||
|
"diagnosis_found_errors": "Found {errors} significant issue(s) related to {category}!",
|
||||||
|
"diagnosis_found_errors_and_warnings": "Found {errors} significant issue(s) (and {warnings} warning(s)) related to {category}!",
|
||||||
|
"diagnosis_found_warnings": "Found {warnings} item(s) that could be improved for {category}.",
|
||||||
|
"diagnosis_everything_ok": "Everything looks good for {category}!",
|
||||||
|
"diagnosis_failed": "Failed to fetch diagnosis result for category '{category}': {error}",
|
||||||
|
"diagnosis_no_cache": "No diagnosis cache yet for category '{category}'",
|
||||||
|
"diagnosis_ip_connected_ipv4": "The server is connected to the Internet through IPv4 !",
|
||||||
|
"diagnosis_ip_no_ipv4": "The server does not have working IPv4.",
|
||||||
|
"diagnosis_ip_connected_ipv6": "The server is connected to the Internet through IPv6 !",
|
||||||
|
"diagnosis_ip_no_ipv6": "The server does not have working IPv6.",
|
||||||
|
"diagnosis_ip_global": "Global IP: <code>{global}</code>",
|
||||||
|
"diagnosis_ip_local": "Local IP: <code>{local}</code>",
|
||||||
|
"diagnosis_ip_not_connected_at_all": "The server does not seem to be connected to the Internet at all!?",
|
||||||
|
"diagnosis_ip_dnsresolution_working": "Domain name resolution is working!",
|
||||||
|
"diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason... Is a firewall blocking DNS requests ?",
|
||||||
|
"diagnosis_ip_broken_resolvconf": "Domain name resolution seems to be broken on your server, which seems related to <code>/etc/resolv.conf</code> not pointing to <code>127.0.0.1</code>.",
|
||||||
|
"diagnosis_ip_weird_resolvconf": "DNS resolution seems to be working, but it looks like you're using a custom <code>/etc/resolv.conf</code>.",
|
||||||
|
"diagnosis_ip_weird_resolvconf_details": "The file <code>/etc/resolv.conf</code> should be a symlink to <code>/etc/resolvconf/run/resolv.conf</code> itself pointing to <code>127.0.0.1</code> (dnsmasq). If you want to manually configure DNS resolvers, please edit <code>/etc/resolv.dnsmasq.conf</code>.",
|
||||||
|
"diagnosis_dns_good_conf": "DNS records are correctly configured for domain {domain} (category {category})",
|
||||||
|
"diagnosis_dns_bad_conf": "Some DNS records are missing or incorrect for domain {domain} (category {category})",
|
||||||
|
"diagnosis_dns_missing_record": "According to the recommended DNS configuration, you should add a DNS record with the following info.<br>Type: <code>{type}</code><br>Name: <code>{name}</code><br>Value: <code>{value}</code>",
|
||||||
|
"diagnosis_dns_discrepancy": "The following DNS record does not seem to follow the recommended configuration:<br>Type: <code>{type}</code><br>Name: <code>{name}</code><br>Current value: <code>{current}</code><br>Excepted value: <code>{value}</code>",
|
||||||
|
"diagnosis_dns_point_to_doc": "Please check the documentation at <a href='https://yunohost.org/dns_config'>https://yunohost.org/dns_config</a> if you need help about configuring DNS records.",
|
||||||
|
"diagnosis_services_running": "Service {service} is running!",
|
||||||
|
"diagnosis_services_conf_broken": "Configuration is broken for service {service}!",
|
||||||
|
"diagnosis_services_bad_status": "Service {service} is {status} :(",
|
||||||
|
"diagnosis_services_bad_status_tip": "You can try to <a href='#/services/{service}'>restart the service</a>, and if it doesn't work, have a look at <a href='#/services/{service}'>the service logs in the webadmin</a> (from the command line, you can do this with <cmd>yunohost service restart {service}</cmd> and <cmd>yunohost service log {service}</cmd>).",
|
||||||
|
"diagnosis_diskusage_verylow": "Storage <code>{mountpoint}</code> (on device <code>{device}</code>) has only {free} ({free_percent}%) space remaining (out of {total}). You should really consider cleaning up some space!",
|
||||||
|
"diagnosis_diskusage_low": "Storage <code>{mountpoint}</code> (on device <code>{device}</code>) has only {free} ({free_percent}%) space remaining (out of {total}). Be careful.",
|
||||||
|
"diagnosis_diskusage_ok": "Storage <code>{mountpoint}</code> (on device <code>{device}</code>) still has {free} ({free_percent}%) space left (out of {total})!",
|
||||||
|
"diagnosis_ram_verylow": "The system has only {available} ({available_percent}%) RAM available! (out of {total})",
|
||||||
|
"diagnosis_ram_low": "The system has {available} ({available_percent}%) RAM available (out of {total}). Be careful.",
|
||||||
|
"diagnosis_ram_ok": "The system still has {available} ({available_percent}%) RAM available out of {total}.",
|
||||||
|
"diagnosis_swap_none": "The system has no swap at all. You should consider adding at least {recommended} of swap to avoid situations where the system runs out of memory.",
|
||||||
|
"diagnosis_swap_notsomuch": "The system has only {total} swap. You should consider having at least {recommended} to avoid situations where the system runs out of memory.",
|
||||||
|
"diagnosis_swap_ok": "The system has {total} of swap!",
|
||||||
|
"diagnosis_mail_outgoing_port_25_ok": "The SMTP mail server is able to send emails (outgoing port 25 is not blocked).",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked": "The SMTP mail server cannot send emails to other servers because outgoing port 25 is blocked in IPv{ipversion}.",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked_details": "You should first try to unblock outgoing port 25 in your internet router interface or your hosting provider interface. (Some hosting provider may require you to send them a support ticket for this).",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Some providers won't let you unblock outgoing port 25 because they don't care about Net Neutrality.<br> - Some of them provide the alternative of <a href='https://yunohost.org/#/smtp_relay'>using a mail server relay</a> though it implies that the relay will be able to spy on your email traffic.<br>- A privacy-friendly alternative is to use a VPN *with a dedicated public IP* to bypass this kind of limits. See <a href='https://yunohost.org/#/vpn_advantage'>https://yunohost.org/#/vpn_advantage</a><br>- You can also consider switching to <a href='https://yunohost.org/#/isp'>a more net neutrality-friendly provider</a>",
|
||||||
|
"diagnosis_mail_ehlo_ok": "The SMTP mail server is reachable from the outside and therefore is able to receive emails!",
|
||||||
|
"diagnosis_mail_ehlo_unreachable": "The SMTP mail server is unreachable from the outside on IPv{ipversion}. It won't be able to receive emails.",
|
||||||
|
"diagnosis_mail_ehlo_unreachable_details": "Could not open a connection on port 25 to your server in IPv{ipversion}. It appears to be unreachable.<br>1. The most common cause for this issue is that port 25 <a href='https://yunohost.org/isp_box_config'>is not correctly forwarded to your server</a>.<br>2. You should also make sure that service postfix is running.<br>3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.",
|
||||||
|
"diagnosis_mail_ehlo_bad_answer": "A non-SMTP service answered on port 25 on IPv{ipversion}",
|
||||||
|
"diagnosis_mail_ehlo_bad_answer_details": "It could be due to an other machine answering instead of your server.",
|
||||||
|
"diagnosis_mail_ehlo_wrong": "A different SMTP mail server answers on IPv{ipversion}. It will probably not be able to receive emails.",
|
||||||
|
"diagnosis_mail_ehlo_wrong_details": "The EHLO received by the remote diagnoser in IPv{ipversion} is different from your server's domain.<br>Received EHLO: <code>{wrong_ehlo}</code><br>Expected: {right_ehlo}<br>The most common cause for this issue is that port 25 <a href='https://yunohost.org/isp_box_config'>is not correctly forwarded to your server</a>. Alternatively, make sure that no firewall or reverse-proxy is interfering.",
|
||||||
|
"diagnosis_mail_ehlo_could_not_diagnose": "Could not diagnose if postfix mail server is reachable from outside in IPv{ipversion}.",
|
||||||
|
"diagnosis_mail_ehlo_could_not_diagnose_details": "Error: {error}",
|
||||||
|
"diagnosis_mail_fcrdns_ok": "Your reverse DNS is correctly configured!",
|
||||||
|
"diagnosis_mail_fcrdns_dns_missing": "No reverse DNS is defined in IPv{ipversion}. Some emails may fail to get delivered or may get flagged as spam.",
|
||||||
|
"diagnosis_mail_fcrdns_nok_details": "You should first try to configure the reverse DNS with <code>{ehlo_domain}</code> in your internet router interface or your hosting provider interface. (Some hosting provider may require you to send them a support ticket for this).",
|
||||||
|
"diagnosis_mail_fcrdns_nok_alternatives_4": "Some providers won't let you configure your reverse DNS (or their feature might be broken...). If you are experiencing issues because of this, consider the following solutions:<br> - Some ISP provide the alternative of <a href='https://yunohost.org/#/smtp_relay'>using a mail server relay</a> though it implies that the relay will be able to spy on your email traffic.<br>- A privacy-friendly alternative is to use a VPN *with a dedicated public IP* to bypass this kind of limits. See <a href='https://yunohost.org/#/vpn_advantage'>https://yunohost.org/#/vpn_advantage</a><br>- Finally, it's also possible to <a href='https://yunohost.org/#/isp'>change of provider</a>",
|
||||||
|
"diagnosis_mail_fcrdns_nok_alternatives_6": "Some providers won't let you configure your reverse DNS (or their feature might be broken...). If your reverse DNS is correctly configured for IPv4, you can try disabling the use of IPv6 when sending emails by running <cmd>yunohost settings set smtp.allow_ipv6 -v off</cmd>. Note: this last solution means that you won't be able to send or receive emails from the few IPv6-only servers out there.",
|
||||||
|
"diagnosis_mail_fcrdns_different_from_ehlo_domain": "The reverse DNS is not correctly configured in IPv{ipversion}. Some emails may fail to get delivered or may get flagged as spam.",
|
||||||
|
"diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Current reverse DNS: <code>{rdns_domain}</code><br>Expected value: <code>{ehlo_domain}</code>",
|
||||||
|
"diagnosis_mail_blacklist_ok": "The IPs and domains used by this server do not appear to be blacklisted",
|
||||||
|
"diagnosis_mail_blacklist_listed_by": "Your IP or domain <code>{item}</code> is blacklisted on {blacklist_name}",
|
||||||
|
"diagnosis_mail_blacklist_reason": "The blacklist reason is: {reason}",
|
||||||
|
"diagnosis_mail_blacklist_website": "After identifying why you are listed and fixed it, feel free to ask for delisting on {blacklist_website}",
|
||||||
|
"diagnosis_mail_queue_ok": "{nb_pending} pending emails in the mail queues",
|
||||||
|
"diagnosis_mail_queue_unavailable": "Can not consult number of pending emails in queue",
|
||||||
|
"diagnosis_mail_queue_unavailable_details": "Error: {error}",
|
||||||
|
"diagnosis_mail_queue_too_big": "Too many pending emails in mail queue ({nb_pending} emails)",
|
||||||
|
"diagnosis_regenconf_allgood": "All configurations files are in line with the recommended configuration!",
|
||||||
|
"diagnosis_regenconf_manually_modified": "Configuration file <code>{file}</code> appears to have been manually modified.",
|
||||||
|
"diagnosis_regenconf_manually_modified_details": "This is probably OK if you know what you're doing! YunoHost will stop updating this file automatically... But beware that YunoHost upgrades could contain important recommended changes. If you want to, you can inspect the differences with <cmd>yunohost tools regen-conf {category} --dry-run --with-diff</cmd> and force the reset to the recommended configuration with <cmd>yunohost tools regen-conf {category} --force</cmd>",
|
||||||
|
"diagnosis_security_all_good": "No critical security vulnerability was found.",
|
||||||
|
"diagnosis_security_vulnerable_to_meltdown": "You appear vulnerable to the Meltdown criticial security vulnerability",
|
||||||
|
"diagnosis_security_vulnerable_to_meltdown_details": "To fix this, you should upgrade your system and reboot to load the new linux kernel (or contact your server provider if this doesn't work). See https://meltdownattack.com/ for more infos.",
|
||||||
|
"diagnosis_description_basesystem": "Base system",
|
||||||
|
"diagnosis_description_ip": "Internet connectivity",
|
||||||
|
"diagnosis_description_dnsrecords": "DNS records",
|
||||||
|
"diagnosis_description_services": "Services status check",
|
||||||
|
"diagnosis_description_systemresources": "System resources",
|
||||||
|
"diagnosis_description_ports": "Ports exposure",
|
||||||
|
"diagnosis_description_web": "Web",
|
||||||
|
"diagnosis_description_mail": "Email",
|
||||||
|
"diagnosis_description_regenconf": "System configurations",
|
||||||
|
"diagnosis_description_security": "Security checks",
|
||||||
|
"diagnosis_ports_could_not_diagnose": "Could not diagnose if ports are reachable from outside in IPv{ipversion}.",
|
||||||
|
"diagnosis_ports_could_not_diagnose_details": "Error: {error}",
|
||||||
|
"diagnosis_ports_unreachable": "Port {port} is not reachable from outside.",
|
||||||
|
"diagnosis_ports_partially_unreachable": "Port {port} is not reachable from outside in IPv{failed}.",
|
||||||
|
"diagnosis_ports_ok": "Port {port} is reachable from outside.",
|
||||||
|
"diagnosis_ports_needed_by": "Exposing this port is needed for {category} features (service {service})",
|
||||||
|
"diagnosis_ports_forwarding_tip": "To fix this issue, you most probably need to configure port forwarding on your internet router as described in <a href='https://yunohost.org/isp_box_config'>https://yunohost.org/isp_box_config</a>",
|
||||||
|
"diagnosis_http_hairpinning_issue": "Your local network does not seem to have hairpinning enabled.",
|
||||||
|
"diagnosis_http_hairpinning_issue_details": "This is probably because of your ISP box / router. As a result, people from outside your local network will be able to access your server as expected, but not people from inside the local network (like you, probably?). You may be able to improve the situation by having a look at <a href='https://yunohost.org/dns_local_network'>https://yunohost.org/dns_local_network</a>",
|
||||||
|
"diagnosis_http_could_not_diagnose": "Could not diagnose if domains are reachable from outside in IPv{ipversion}.",
|
||||||
|
"diagnosis_http_could_not_diagnose_details": "Error: {error}",
|
||||||
|
"diagnosis_http_ok": "Domain {domain} is reachable through HTTP from outside the local network.",
|
||||||
|
"diagnosis_http_timeout": "Timed-out while trying to contact your server from outside. It appears to be unreachable.<br>1. The most common cause for this issue is that port 80 (and 443) <a href='https://yunohost.org/isp_box_config'>are not correctly forwarded to your server</a>.<br>2. You should also make sure that the service nginx is running<br>3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.",
|
||||||
|
"diagnosis_http_connection_error": "Connection error: could not connect to the requested domain, it's very likely unreachable.",
|
||||||
|
"diagnosis_http_bad_status_code": "It looks like another machine (maybe your internet router) answered instead of your server.<br>1. The most common cause for this issue is that port 80 (and 443) <a href='https://yunohost.org/isp_box_config'>are not correctly forwarded to your server</a>.<br>2. On more complex setups: make sure that no firewall or reverse-proxy is interfering.",
|
||||||
|
"diagnosis_http_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network.",
|
||||||
|
"diagnosis_http_partially_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network in IPv{failed}, though it works in IPv{passed}.",
|
||||||
|
"diagnosis_http_nginx_conf_not_up_to_date": "This domain's nginx configuration appears to have been modified manually, and prevents YunoHost from diagnosing if it's reachable on HTTP.",
|
||||||
|
"diagnosis_http_nginx_conf_not_up_to_date_details": "To fix the situation, inspect the difference with the command line using <cmd>yunohost tools regen-conf nginx --dry-run --with-diff</cmd> and if you're ok, apply the changes with <cmd>yunohost tools regen-conf nginx --force</cmd>.",
|
||||||
|
"diagnosis_unknown_categories": "The following categories are unknown: {categories}",
|
||||||
|
"diagnosis_never_ran_yet": "It looks like this server was setup recently and there's no diagnosis report to show yet. You should start by running a full diagnosis, either from the webadmin or using 'yunohost diagnosis run' from the command line.",
|
||||||
|
"domain_cannot_remove_main": "You cannot remove '{domain:s}' since it's the main domain, you first need to set another domain as the main domain using 'yunohost domain main-domain -n <another-domain>'; here is the list of candidate domains: {other_domains:s}",
|
||||||
|
"domain_cannot_add_xmpp_upload": "You cannot add domains starting with 'xmpp-upload.'. This kind of name is reserved for the XMPP upload feature integrated in YunoHost.",
|
||||||
|
"domain_cannot_remove_main_add_new_one": "You cannot remove '{domain:s}' since it's the main domain and your only domain, you need to first add another domain using 'yunohost domain add <another-domain.com>', then set is as the main domain using 'yunohost domain main-domain -n <another-domain.com>' and then you can remove the domain '{domain:s}' using 'yunohost domain remove {domain:s}'.'",
|
||||||
"domain_cert_gen_failed": "Could not generate certificate",
|
"domain_cert_gen_failed": "Could not generate certificate",
|
||||||
"domain_created": "Domain created",
|
"domain_created": "Domain created",
|
||||||
"domain_creation_failed": "Could not create domain",
|
"domain_creation_failed": "Unable to create domain {domain}: {error}",
|
||||||
"domain_deleted": "Domain deleted",
|
"domain_deleted": "Domain deleted",
|
||||||
"domain_deletion_failed": "Could not delete domain",
|
"domain_deletion_failed": "Unable to delete domain {domain}: {error}",
|
||||||
"domain_dns_conf_is_just_a_recommendation": "This command shows you the *recommended* configuration. It does not actually set up the DNS configuration for you. It is your responsability to configure your DNS zone in your registrar according to this recommendation.",
|
"domain_dns_conf_is_just_a_recommendation": "This command shows you the *recommended* configuration. It does not actually set up the DNS configuration for you. It is your responsability to configure your DNS zone in your registrar according to this recommendation.",
|
||||||
"domain_dyndns_already_subscribed": "You have already subscribed to a DynDNS domain",
|
"domain_dyndns_already_subscribed": "You have already subscribed to a DynDNS domain",
|
||||||
"domain_dyndns_root_unknown": "Unknown DynDNS root domain",
|
"domain_dyndns_root_unknown": "Unknown DynDNS root domain",
|
||||||
|
@ -171,6 +268,8 @@
|
||||||
"domains_available": "Available domains:",
|
"domains_available": "Available domains:",
|
||||||
"done": "Done",
|
"done": "Done",
|
||||||
"downloading": "Downloading…",
|
"downloading": "Downloading…",
|
||||||
|
"dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state… You can try to solve this issue by connecting through SSH and running `sudo dpkg --configure -a`.",
|
||||||
|
"dpkg_lock_not_available": "This command can't be run right now because another program seems to be using the lock of dpkg (the system package manager)",
|
||||||
"dyndns_could_not_check_provide": "Could not check if {provider:s} can provide {domain:s}.",
|
"dyndns_could_not_check_provide": "Could not check if {provider:s} can provide {domain:s}.",
|
||||||
"dyndns_could_not_check_available": "Could not check if {domain:s} is available on {provider:s}.",
|
"dyndns_could_not_check_available": "Could not check if {domain:s} is available on {provider:s}.",
|
||||||
"dyndns_cron_installed": "DynDNS cron job created",
|
"dyndns_cron_installed": "DynDNS cron job created",
|
||||||
|
@ -181,14 +280,11 @@
|
||||||
"dyndns_key_generating": "Generating DNS key… It may take a while.",
|
"dyndns_key_generating": "Generating DNS key… It may take a while.",
|
||||||
"dyndns_key_not_found": "DNS key not found for the domain",
|
"dyndns_key_not_found": "DNS key not found for the domain",
|
||||||
"dyndns_no_domain_registered": "No domain registered with DynDNS",
|
"dyndns_no_domain_registered": "No domain registered with DynDNS",
|
||||||
"dyndns_provider_unreachable": "Unable to reach Dyndns provider {provider}: either your YunoHost is not correctly connected to the internet or the dynette server is down.",
|
"dyndns_provider_unreachable": "Unable to reach DynDNS provider {provider}: either your YunoHost is not correctly connected to the internet or the dynette server is down.",
|
||||||
"dyndns_registered": "DynDNS domain registered",
|
"dyndns_registered": "DynDNS domain registered",
|
||||||
"dyndns_registration_failed": "Could not register DynDNS domain: {error:s}",
|
"dyndns_registration_failed": "Could not register DynDNS domain: {error:s}",
|
||||||
"dyndns_domain_not_provided": "DynDNS provider {provider:s} cannot provide domain {domain:s}.",
|
"dyndns_domain_not_provided": "DynDNS provider {provider:s} cannot provide domain {domain:s}.",
|
||||||
"dyndns_unavailable": "The domain '{domain:s}' is unavailable.",
|
"dyndns_unavailable": "The domain '{domain:s}' is unavailable.",
|
||||||
"edit_group_not_allowed": "You are not allowed to edit the group {group:s}",
|
|
||||||
"edit_permission_with_group_all_users_not_allowed": "You are not allowed to edit permission for the group 'all_users', use 'yunohost user permission clear APP' or 'yunohost user permission add APP -u USER' instead.",
|
|
||||||
"error_when_removing_sftpuser_group": "Could not remove the sftpusers group",
|
|
||||||
"executing_command": "Executing command '{command:s}'…",
|
"executing_command": "Executing command '{command:s}'…",
|
||||||
"executing_script": "Executing script '{script:s}'…",
|
"executing_script": "Executing script '{script:s}'…",
|
||||||
"extracting": "Extracting…",
|
"extracting": "Extracting…",
|
||||||
|
@ -197,7 +293,7 @@
|
||||||
"file_does_not_exist": "The file {path:s} does not exist.",
|
"file_does_not_exist": "The file {path:s} does not exist.",
|
||||||
"firewall_reload_failed": "Could not reload the firewall",
|
"firewall_reload_failed": "Could not reload the firewall",
|
||||||
"firewall_reloaded": "Firewall reloaded",
|
"firewall_reloaded": "Firewall reloaded",
|
||||||
"firewall_rules_cmd_failed": "Some firewall rules commands have failed. More info in log.",
|
"firewall_rules_cmd_failed": "Some firewall rule commands have failed. More info in log.",
|
||||||
"global_settings_bad_choice_for_enum": "Bad choice for setting {setting:s}, received '{choice:s}', but available choices are: {available_choices:s}",
|
"global_settings_bad_choice_for_enum": "Bad choice for setting {setting:s}, received '{choice:s}', but available choices are: {available_choices:s}",
|
||||||
"global_settings_bad_type_for_setting": "Bad type for setting {setting:s}, received {received_type:s}, expected {expected_type:s}",
|
"global_settings_bad_type_for_setting": "Bad type for setting {setting:s}, received {received_type:s}, expected {expected_type:s}",
|
||||||
"global_settings_cant_open_settings": "Could not open settings file, reason: {reason:s}",
|
"global_settings_cant_open_settings": "Could not open settings file, reason: {reason:s}",
|
||||||
|
@ -205,6 +301,7 @@
|
||||||
"global_settings_cant_write_settings": "Could not save settings file, reason: {reason:s}",
|
"global_settings_cant_write_settings": "Could not save settings file, reason: {reason:s}",
|
||||||
"global_settings_key_doesnt_exists": "The key '{settings_key:s}' does not exist in the global settings, you can see all the available keys by running 'yunohost settings list'",
|
"global_settings_key_doesnt_exists": "The key '{settings_key:s}' does not exist in the global settings, you can see all the available keys by running 'yunohost settings list'",
|
||||||
"global_settings_reset_success": "Previous settings now backed up to {path:s}",
|
"global_settings_reset_success": "Previous settings now backed up to {path:s}",
|
||||||
|
"global_settings_setting_pop3_enabled": "Enable the POP3 protocol for the mail server",
|
||||||
"global_settings_setting_example_bool": "Example boolean option",
|
"global_settings_setting_example_bool": "Example boolean option",
|
||||||
"global_settings_setting_example_enum": "Example enum option",
|
"global_settings_setting_example_enum": "Example enum option",
|
||||||
"global_settings_setting_example_int": "Example int option",
|
"global_settings_setting_example_int": "Example int option",
|
||||||
|
@ -216,26 +313,32 @@
|
||||||
"global_settings_setting_security_postfix_compatibility": "Compatibility vs. security tradeoff for the Postfix server. Affects the ciphers (and other security-related aspects)",
|
"global_settings_setting_security_postfix_compatibility": "Compatibility vs. security tradeoff for the Postfix server. Affects the ciphers (and other security-related aspects)",
|
||||||
"global_settings_unknown_setting_from_settings_file": "Unknown key in settings: '{setting_key:s}', discard it and save it in /etc/yunohost/settings-unknown.json",
|
"global_settings_unknown_setting_from_settings_file": "Unknown key in settings: '{setting_key:s}', discard it and save it in /etc/yunohost/settings-unknown.json",
|
||||||
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Allow the use of (deprecated) DSA hostkey for the SSH daemon configuration",
|
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Allow the use of (deprecated) DSA hostkey for the SSH daemon configuration",
|
||||||
|
"global_settings_setting_smtp_allow_ipv6": "Allow the use of IPv6 to receive and send mail",
|
||||||
"global_settings_unknown_type": "Unexpected situation, the setting {setting:s} appears to have the type {unknown_type:s} but it is not a type supported by the system.",
|
"global_settings_unknown_type": "Unexpected situation, the setting {setting:s} appears to have the type {unknown_type:s} but it is not a type supported by the system.",
|
||||||
"good_practices_about_admin_password": "You are now about to define a new administration password. The password should be at-least 8 characters—though it is good practice to use a longer password (i.e. a passphrase) and/or to use a variation of characters (uppercase, lowercase, digits and special characters).",
|
"good_practices_about_admin_password": "You are now about to define a new administration password. The password should be at least 8 characters long—though it is good practice to use a longer password (i.e. a passphrase) and/or to use a variation of characters (uppercase, lowercase, digits and special characters).",
|
||||||
"good_practices_about_user_password": "You are now about to define a new user password. The password should be at least 8 characters—though it is good practice to use longer password (i.e. a passphrase) and/or to a variation of characters (uppercase, lowercase, digits and special characters).",
|
"good_practices_about_user_password": "You are now about to define a new user password. The password should be at least 8 characters long—though it is good practice to use a longer password (i.e. a passphrase) and/or to a variation of characters (uppercase, lowercase, digits and special characters).",
|
||||||
"group_already_allowed": "Group '{group:s}' already has permission '{permission:s}' turned on for the app '{app:s}'",
|
"group_already_exist": "Group {group} already exists",
|
||||||
"group_already_disallowed": "Group '{group:s}' already has permissions '{permission:s}' turned off for the app '{app:s}'",
|
"group_already_exist_on_system": "Group {group} already exists in the system groups",
|
||||||
"group_name_already_exist": "Group {name:s} already exists",
|
"group_already_exist_on_system_but_removing_it": "Group {group} already exists in the system groups, but YunoHost will remove it…",
|
||||||
"group_created": "Group '{group}' created",
|
"group_created": "Group '{group}' created",
|
||||||
"group_creation_failed": "Could not create the group '{group}'",
|
"group_creation_failed": "Could not create the group '{group}': {error}",
|
||||||
|
"group_cannot_edit_all_users": "The group 'all_users' cannot be edited manually. It is a special group meant to contain all users registered in YunoHost",
|
||||||
|
"group_cannot_edit_visitors": "The group 'visitors' cannot be edited manually. It is a special group representing anonymous visitors",
|
||||||
|
"group_cannot_edit_primary_group": "The group '{group}' cannot be edited manually. It is the primary group meant to contain only one specific user.",
|
||||||
|
"group_cannot_be_deleted": "The group {group} cannot be deleted manually.",
|
||||||
"group_deleted": "Group '{group}' deleted",
|
"group_deleted": "Group '{group}' deleted",
|
||||||
"group_deletion_failed": "Could not delete the group '{group}'",
|
"group_deletion_failed": "Could not delete the group '{group}': {error}",
|
||||||
"group_deletion_not_allowed": "The group {group:s} cannot be deleted manually.",
|
|
||||||
"group_unknown": "The group '{group:s}' is unknown",
|
"group_unknown": "The group '{group:s}' is unknown",
|
||||||
"group_updated": "Group '{group}' updated",
|
"group_updated": "Group '{group}' updated",
|
||||||
"group_update_failed": "Could not update the group '{group}'",
|
"group_update_failed": "Could not update the group '{group}': {error}",
|
||||||
|
"group_user_already_in_group": "User {user} is already in group {group}",
|
||||||
|
"group_user_not_in_group": "User {user} is not in group {group}",
|
||||||
"hook_exec_failed": "Could not run script: {path:s}",
|
"hook_exec_failed": "Could not run script: {path:s}",
|
||||||
"hook_exec_not_terminated": "Script did not finish properly: {path:s}",
|
"hook_exec_not_terminated": "Script did not finish properly: {path:s}",
|
||||||
"hook_json_return_error": "Could not read return from hook {path:s}. Error: {msg:s}. Raw content: {raw_content}",
|
"hook_json_return_error": "Could not read return from hook {path:s}. Error: {msg:s}. Raw content: {raw_content}",
|
||||||
"hook_list_by_invalid": "This property can not be used to list hooks",
|
"hook_list_by_invalid": "This property can not be used to list hooks",
|
||||||
"hook_name_unknown": "Unknown hook name '{name:s}'",
|
"hook_name_unknown": "Unknown hook name '{name:s}'",
|
||||||
"installation_complete": "Installation complete",
|
"installation_complete": "Installation completed",
|
||||||
"installation_failed": "Something went wrong with the installation",
|
"installation_failed": "Something went wrong with the installation",
|
||||||
"ip6tables_unavailable": "You cannot play with ip6tables here. You are either in a container or your kernel does not support it",
|
"ip6tables_unavailable": "You cannot play with ip6tables here. You are either in a container or your kernel does not support it",
|
||||||
"iptables_unavailable": "You cannot play with iptables here. You are either in a container or your kernel does not support it",
|
"iptables_unavailable": "You cannot play with iptables here. You are either in a container or your kernel does not support it",
|
||||||
|
@ -245,18 +348,16 @@
|
||||||
"log_help_to_get_log": "To view the log of the operation '{desc}', use the command 'yunohost log display {name}'",
|
"log_help_to_get_log": "To view the log of the operation '{desc}', use the command 'yunohost log display {name}'",
|
||||||
"log_link_to_failed_log": "Could not complete the operation '{desc}'. Please provide the full log of this operation by <a href=\"#/tools/logs/{name}\">clicking here</a> to get help",
|
"log_link_to_failed_log": "Could not complete the operation '{desc}'. Please provide the full log of this operation by <a href=\"#/tools/logs/{name}\">clicking here</a> to get help",
|
||||||
"log_help_to_get_failed_log": "The operation '{desc}' could not be completed. Please share the full log of this operation using the command 'yunohost log display {name} --share' to get help",
|
"log_help_to_get_failed_log": "The operation '{desc}' could not be completed. Please share the full log of this operation using the command 'yunohost log display {name} --share' to get help",
|
||||||
"log_does_exists": "There is not operation log with the name '{log}', use 'yunohost log list' to see all available operation logs",
|
"log_does_exists": "There is no operation log with the name '{log}', use 'yunohost log list' to see all available operation logs",
|
||||||
"log_operation_unit_unclosed_properly": "Operation unit has not been closed properly",
|
"log_operation_unit_unclosed_properly": "Operation unit has not been closed properly",
|
||||||
"log_app_addaccess": "Add access to '{}'",
|
"log_app_change_url": "Change the URL of the '{}' app",
|
||||||
"log_app_removeaccess": "Remove access to '{}'",
|
"log_app_install": "Install the '{}' app",
|
||||||
"log_app_clearaccess": "Remove all access to '{}'",
|
"log_app_remove": "Remove the '{}' app",
|
||||||
"log_app_fetchlist": "Add an application list",
|
"log_app_upgrade": "Upgrade the '{}' app",
|
||||||
"log_app_removelist": "Remove an application list",
|
"log_app_makedefault": "Make '{}' the default app",
|
||||||
"log_app_change_url": "Change the URL of '{}' application",
|
"log_app_action_run": "Run action of the '{}' app",
|
||||||
"log_app_install": "Install the '{}' application",
|
"log_app_config_show_panel": "Show the config panel of the '{}' app",
|
||||||
"log_app_remove": "Remove the '{}' application",
|
"log_app_config_apply": "Apply config to the '{}' app",
|
||||||
"log_app_upgrade": "Upgrade the '{}' application",
|
|
||||||
"log_app_makedefault": "Make '{}' the default application",
|
|
||||||
"log_available_on_yunopaste": "This log is now available via {url}",
|
"log_available_on_yunopaste": "This log is now available via {url}",
|
||||||
"log_backup_restore_system": "Restore system from a backup archive",
|
"log_backup_restore_system": "Restore system from a backup archive",
|
||||||
"log_backup_restore_app": "Restore '{}' from a backup archive",
|
"log_backup_restore_app": "Restore '{}' from a backup archive",
|
||||||
|
@ -266,38 +367,37 @@
|
||||||
"log_domain_remove": "Remove '{}' domain from system configuration",
|
"log_domain_remove": "Remove '{}' domain from system configuration",
|
||||||
"log_dyndns_subscribe": "Subscribe to a YunoHost subdomain '{}'",
|
"log_dyndns_subscribe": "Subscribe to a YunoHost subdomain '{}'",
|
||||||
"log_dyndns_update": "Update the IP associated with your YunoHost subdomain '{}'",
|
"log_dyndns_update": "Update the IP associated with your YunoHost subdomain '{}'",
|
||||||
"log_letsencrypt_cert_install": "Install a Let's encrypt certificate on '{}' domain",
|
"log_letsencrypt_cert_install": "Install a Let's Encrypt certificate on '{}' domain",
|
||||||
"log_permission_add": "Add the '{}' permission for the app '{}'",
|
"log_permission_create": "Create permission '{}'",
|
||||||
"log_permission_remove": "Remove permission '{}'",
|
"log_permission_delete": "Delete permission '{}'",
|
||||||
"log_permission_update": "Update permission '{}' for app '{}'",
|
"log_permission_url": "Update url related to permission '{}'",
|
||||||
"log_selfsigned_cert_install": "Install self signed certificate on '{}' domain",
|
"log_selfsigned_cert_install": "Install self-signed certificate on '{}' domain",
|
||||||
"log_letsencrypt_cert_renew": "Renew '{}' Let's encrypt certificate",
|
"log_letsencrypt_cert_renew": "Renew '{}' Let's Encrypt certificate",
|
||||||
"log_regen_conf": "Regenerate system configurations '{}'",
|
"log_regen_conf": "Regenerate system configurations '{}'",
|
||||||
"log_user_create": "Add '{}' user",
|
"log_user_create": "Add '{}' user",
|
||||||
"log_user_delete": "Delete '{}' user",
|
"log_user_delete": "Delete '{}' user",
|
||||||
"log_user_group_add": "Add '{}' group",
|
"log_user_group_create": "Create '{}' group",
|
||||||
"log_user_group_delete": "Delete '{}' group",
|
"log_user_group_delete": "Delete '{}' group",
|
||||||
"log_user_group_update": "Update '{}' group",
|
"log_user_group_update": "Update '{}' group",
|
||||||
"log_user_update": "Update user info of '{}'",
|
"log_user_update": "Update user info of '{}'",
|
||||||
"log_user_permission_add": "Update '{}' permission",
|
"log_user_permission_update": "Update accesses for permission '{}'",
|
||||||
"log_user_permission_remove": "Update '{}' permission",
|
"log_user_permission_reset": "Reset permission '{}'",
|
||||||
"log_tools_maindomain": "Make '{}' the main domain",
|
"log_domain_main_domain": "Make '{}' the main domain",
|
||||||
"log_tools_migrations_migrate_forward": "Migrate forward",
|
"log_tools_migrations_migrate_forward": "Run migrations",
|
||||||
"log_tools_postinstall": "Postinstall your YunoHost server",
|
"log_tools_postinstall": "Postinstall your YunoHost server",
|
||||||
"log_tools_upgrade": "Upgrade system packages",
|
"log_tools_upgrade": "Upgrade system packages",
|
||||||
"log_tools_shutdown": "Shutdown your server",
|
"log_tools_shutdown": "Shutdown your server",
|
||||||
"log_tools_reboot": "Reboot your server",
|
"log_tools_reboot": "Reboot your server",
|
||||||
"ldap_init_failed_to_create_admin": "LDAP initialization could not create admin user",
|
"ldap_init_failed_to_create_admin": "LDAP initialization could not create admin user",
|
||||||
"ldap_initialized": "LDAP initialized",
|
"ldap_initialized": "LDAP initialized",
|
||||||
"license_undefined": "undefined",
|
|
||||||
"mail_alias_remove_failed": "Could not remove e-mail alias '{mail:s}'",
|
"mail_alias_remove_failed": "Could not remove e-mail alias '{mail:s}'",
|
||||||
"mail_domain_unknown": "Unknown e-mail address for domain '{domain:s}'",
|
"mail_domain_unknown": "Invalid e-mail address for domain '{domain:s}'. Please, use a domain administrated by this server.",
|
||||||
"mail_forward_remove_failed": "Could not remove e-mail forwarding '{mail:s}'",
|
"mail_forward_remove_failed": "Could not remove e-mail forwarding '{mail:s}'",
|
||||||
"mailbox_disabled": "E-mail turned off for user {user:s}",
|
"mailbox_disabled": "E-mail turned off for user {user:s}",
|
||||||
"mailbox_used_space_dovecot_down": "The Dovecot mailbox service needs to be up, if you want to fetch used mailbox space",
|
"mailbox_used_space_dovecot_down": "The Dovecot mailbox service needs to be up if you want to fetch used mailbox space",
|
||||||
"mail_unavailable": "This e-mail address is reserved and shall be automatically allocated to the very first user",
|
"mail_unavailable": "This e-mail address is reserved and shall be automatically allocated to the very first user",
|
||||||
"maindomain_change_failed": "Could not change the main domain",
|
"main_domain_change_failed": "Unable to change the main domain",
|
||||||
"maindomain_changed": "The main domain now changed",
|
"main_domain_changed": "The main domain has been changed",
|
||||||
"migrate_tsig_end": "Migration to HMAC-SHA-512 finished",
|
"migrate_tsig_end": "Migration to HMAC-SHA-512 finished",
|
||||||
"migrate_tsig_failed": "Could not migrate the DynDNS domain '{domain}' to HMAC-SHA-512, rolling back. Error: {error_code}, {error}",
|
"migrate_tsig_failed": "Could not migrate the DynDNS domain '{domain}' to HMAC-SHA-512, rolling back. Error: {error_code}, {error}",
|
||||||
"migrate_tsig_start": "Insufficiently secure key algorithm detected for TSIG signature of the domain '{domain}', initiating migration to the more secure HMAC-SHA-512",
|
"migrate_tsig_start": "Insufficiently secure key algorithm detected for TSIG signature of the domain '{domain}', initiating migration to the more secure HMAC-SHA-512",
|
||||||
|
@ -315,48 +415,51 @@
|
||||||
"migration_description_0007_ssh_conf_managed_by_yunohost_step1": "Let the SSH configuration be managed by YunoHost (step 1, automatic)",
|
"migration_description_0007_ssh_conf_managed_by_yunohost_step1": "Let the SSH configuration be managed by YunoHost (step 1, automatic)",
|
||||||
"migration_description_0008_ssh_conf_managed_by_yunohost_step2": "Let the SSH configuration be managed by YunoHost (step 2, manual)",
|
"migration_description_0008_ssh_conf_managed_by_yunohost_step2": "Let the SSH configuration be managed by YunoHost (step 2, manual)",
|
||||||
"migration_description_0009_decouple_regenconf_from_services": "Decouple the regen-conf mechanism from services",
|
"migration_description_0009_decouple_regenconf_from_services": "Decouple the regen-conf mechanism from services",
|
||||||
"migration_description_0010_migrate_to_apps_json": "Remove deprecated applists and use the new unified 'apps.json' list instead",
|
"migration_description_0010_migrate_to_apps_json": "Remove deprecated apps catalogs and use the new unified 'apps.json' list instead (outdated, replaced by migration 13)",
|
||||||
"migration_description_0011_setup_group_permission": "Set up user group and set up permission for apps and services",
|
"migration_description_0011_setup_group_permission": "Set up user groups and permissions for apps and services",
|
||||||
"migration_description_0012_postgresql_password_to_md5_authentication": "Force PostgreSQL authentication to use MD5 for local connections",
|
"migration_description_0012_postgresql_password_to_md5_authentication": "Force PostgreSQL authentication to use MD5 for local connections",
|
||||||
|
"migration_description_0013_futureproof_apps_catalog_system": "Migrate to the new future-proof apps catalog system",
|
||||||
|
"migration_description_0014_remove_app_status_json": "Remove legacy status.json app files",
|
||||||
"migration_0003_start": "Starting migration to Stretch. The logs will be available in {logfile}.",
|
"migration_0003_start": "Starting migration to Stretch. The logs will be available in {logfile}.",
|
||||||
"migration_0003_patching_sources_list": "Patching the sources.lists…",
|
"migration_0003_patching_sources_list": "Patching the sources.lists…",
|
||||||
"migration_0003_main_upgrade": "Starting main upgrade…",
|
"migration_0003_main_upgrade": "Starting main upgrade…",
|
||||||
"migration_0003_fail2ban_upgrade": "Starting the Fail2Ban upgrade…",
|
"migration_0003_fail2ban_upgrade": "Starting the Fail2Ban upgrade…",
|
||||||
"migration_0003_restoring_origin_nginx_conf": "Your file /etc/nginx/nginx.conf was edited somehow. The migration is going to reset to its original state first… The previous file will be available as {backup_dest}.",
|
"migration_0003_restoring_origin_nginx_conf": "Your file /etc/nginx/nginx.conf was edited somehow. The migration is going to reset it to its original state first… The previous file will be available as {backup_dest}.",
|
||||||
"migration_0003_yunohost_upgrade": "Starting the YunoHost package upgrade… The migration will end, but the actual upgrade will happen immediately afterwards. After the operation is complete, you might have to log in on the webadmin page again.",
|
"migration_0003_yunohost_upgrade": "Starting the YunoHost package upgrade… The migration will end, but the actual upgrade will happen immediately afterwards. After the operation is complete, you might have to log in to the webadmin page again.",
|
||||||
"migration_0003_not_jessie": "The current Debian distribution is not Jessie!",
|
"migration_0003_not_jessie": "The current Debian distribution is not Jessie!",
|
||||||
"migration_0003_system_not_fully_up_to_date": "Your system is not fully up-to-date. Please perform a regular upgrade before running the migration to Stretch.",
|
"migration_0003_system_not_fully_up_to_date": "Your system is not fully up-to-date. Please perform a regular upgrade before running the migration to Stretch.",
|
||||||
"migration_0003_still_on_jessie_after_main_upgrade": "Something went wrong during the main upgrade: Is the system still on Jessie‽ To investigate the issue, please look at {log}:s…",
|
"migration_0003_still_on_jessie_after_main_upgrade": "Something went wrong during the main upgrade: Is the system still on Jessie‽ To investigate the issue, please look at {log}:s…",
|
||||||
"migration_0003_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade.\n\nAdditionally, the port for SMTP, used by external e-mail clients (like Thunderbird or K9-Mail) was changed from 465 (SSL/TLS) to 587 (STARTTLS). The old port (465) will automatically be closed, and the new port (587) will be opened in the firewall. You and your users *will* have to adapt the configuration of your e-mail clients accordingly.",
|
"migration_0003_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade.\n\nAdditionally, the port for SMTP, used by external e-mail clients (like Thunderbird or K9-Mail) was changed from 465 (SSL/TLS) to 587 (STARTTLS). The old port (465) will automatically be closed, and the new port (587) will be opened in the firewall. You and your users *will* have to adapt the configuration of your e-mail clients accordingly.",
|
||||||
"migration_0003_problematic_apps_warning": "Please note that the following possibly problematic installed apps were detected. It looks like those were not installed from an applist, or are not flagged as 'working'. Consequently, it cannot be guaranteed that they will still work after the upgrade: {problematic_apps}",
|
"migration_0003_problematic_apps_warning": "Please note that the following possibly problematic installed apps were detected. It looks like those were not installed from an app catalog, or are not flagged as 'working'. Consequently, it cannot be guaranteed that they will still work after the upgrade: {problematic_apps}",
|
||||||
"migration_0003_modified_files": "Please note that the following files were found to be manually modified and might be overwritten following the upgrade: {manually_modified_files}",
|
"migration_0003_modified_files": "Please note that the following files were found to be manually modified and might be overwritten following the upgrade: {manually_modified_files}",
|
||||||
"migration_0005_postgresql_94_not_installed": "PostgreSQL was not installed on your system. Nothing to do.",
|
"migration_0005_postgresql_94_not_installed": "PostgreSQL was not installed on your system. Nothing to do.",
|
||||||
"migration_0005_postgresql_96_not_installed": "PostgreSQL 9.4 is installed, but not postgresql 9.6‽ Something weird might have happened on your system:(…",
|
"migration_0005_postgresql_96_not_installed": "PostgreSQL 9.4 is installed, but not postgresql 9.6‽ Something weird might have happened on your system :(…",
|
||||||
"migration_0005_not_enough_space": "Make sufficient space available in {path} to run the migration.",
|
"migration_0005_not_enough_space": "Make sufficient space available in {path} to run the migration.",
|
||||||
"migration_0006_disclaimer": "YunoHost now expects admin and root passwords to be synchronized. By running this migration, your root password is going to be replaced by the admin password.",
|
"migration_0006_disclaimer": "YunoHost now expects the admin and root passwords to be synchronized. This migration replaces your root password with the admin password.",
|
||||||
"migration_0007_cancelled": "YunoHost has failed to improve the way your SSH conf is managed.",
|
"migration_0007_cancelled": "Could not improve the way your SSH configuration is managed.",
|
||||||
"migration_0007_cannot_restart": "SSH can't be restarted after trying to cancel migration number 6.",
|
"migration_0007_cannot_restart": "SSH can't be restarted after trying to cancel migration number 6.",
|
||||||
"migration_0008_general_disclaimer": "To improve the security of your server, it is recommended to let YunoHost manage the SSH configuration. Your current SSH setup differs from the recommendation. If you let YunoHost reconfigure it, the way you connect to your server through SSH will change thusly:",
|
"migration_0008_general_disclaimer": "To improve the security of your server, it is recommended to let YunoHost manage the SSH configuration. Your current SSH setup differs from the recommendation. If you let YunoHost reconfigure it, the way you connect to your server through SSH will change thusly:",
|
||||||
"migration_0008_port": "• You will have to connect using port 22 instead of your current custom SSH port. Feel free to reconfigure it;",
|
"migration_0008_port": "• You will have to connect using port 22 instead of your current custom SSH port. Feel free to reconfigure it;",
|
||||||
"migration_0008_root": "• You will not be able to connect as root through SSH. Instead you should use the admin user;",
|
"migration_0008_root": "• You will not be able to connect as root through SSH. Instead you should use the admin user;",
|
||||||
"migration_0008_dsa": "• The DSA key will be turned off. Hence, you might need to invalidate a spooky warning from your SSH client, and recheck the fingerprint of your server;",
|
"migration_0008_dsa": "• The DSA key will be turned off. Hence, you might need to invalidate a spooky warning from your SSH client, and recheck the fingerprint of your server;",
|
||||||
"migration_0008_warning": "If you understand those warnings and agree to let YunoHost override your current configuration, run the migration. Otherwise, you can also skip the migration - though it is not recommended.",
|
"migration_0008_warning": "If you understand those warnings and want YunoHost to override your current configuration, run the migration. Otherwise, you can also skip the migration, though it is not recommended.",
|
||||||
"migration_0008_no_warning": "No major risk indentified concerning overriding your SSH configuration—one can however not be absolutely sure ;)! Run the migration to override it. Otherwise, you can also skip the migration - though it is not recommended.",
|
"migration_0008_no_warning": "Overriding your SSH configuration should be safe, though this cannot be promised! Run the migration to override it. Otherwise, you can also skip the migration, though it is not recommended.",
|
||||||
"migration_0009_not_needed": "This migration already happened somehow… (?) Skipping.",
|
"migration_0009_not_needed": "This migration already happened somehow… (?) Skipping.",
|
||||||
"migration_0011_backup_before_migration": "Creating a backup of LDAP database and apps settings prior to the actual migration.",
|
"migration_0011_backup_before_migration": "Creating a backup of LDAP database and apps settings prior to the actual migration.",
|
||||||
"migration_0011_can_not_backup_before_migration": "Could not back up the system prior to migration. Error: {error:s}",
|
"migration_0011_can_not_backup_before_migration": "The backup of the system could not be completed before the migration failed. Error: {error:s}",
|
||||||
"migration_0011_create_group": "Creating a group for each user…",
|
"migration_0011_create_group": "Creating a group for each user…",
|
||||||
"migration_0011_done": "Migration successful. You are now able to manage usergroups.",
|
"migration_0011_done": "Migration completed. You are now able to manage usergroups.",
|
||||||
"migration_0011_LDAP_config_dirty": "It look like that you customized your LDAP configuration. For this migration the LDAP configuration needs to be updated.\nYou need to save your actual configuration, reintialize the original configuration by running 'yunohost tools regen-conf -f' and retry the migration",
|
"migration_0011_slapd_config_will_be_overwritten": "It looks like you manually edited the slapd configuration. For this critical migration, YunoHost needs to force the update of the slapd configuration. The original files will be backuped in {conf_backup_folder}.",
|
||||||
"migration_0011_LDAP_update_failed": "Could not update LDAP. Error: {error:s}",
|
"migration_0011_LDAP_update_failed": "Could not update LDAP. Error: {error:s}",
|
||||||
"migration_0011_migrate_permission": "Migrating permissions from apps settings to LDAP…",
|
"migration_0011_migrate_permission": "Migrating permissions from apps settings to LDAP…",
|
||||||
"migration_0011_migration_failed_trying_to_rollback": "Migration failed… trying to roll back the system.",
|
"migration_0011_migration_failed_trying_to_rollback": "Could not migrate… trying to roll back the system.",
|
||||||
"migration_0011_rollback_success": "System rolled back.",
|
"migration_0011_rollback_success": "System rolled back.",
|
||||||
"migration_0011_update_LDAP_database": "Updating LDAP database…",
|
"migration_0011_update_LDAP_database": "Updating LDAP database…",
|
||||||
"migration_0011_update_LDAP_schema": "Updating LDAP schema…",
|
"migration_0011_update_LDAP_schema": "Updating LDAP schema…",
|
||||||
|
"migration_0011_failed_to_remove_stale_object": "Could not remove stale object {dn}: {error}",
|
||||||
"migrations_already_ran": "Those migrations are already done: {ids}",
|
"migrations_already_ran": "Those migrations are already done: {ids}",
|
||||||
"migrations_cant_reach_migration_file": "Could not access migrations files at path %s",
|
"migrations_cant_reach_migration_file": "Could not access migrations files at the path '%s'",
|
||||||
"migrations_dependencies_not_satisfied": "Cannot run migration {id} because first you need to run these migrations: {dependencies_id}",
|
"migrations_dependencies_not_satisfied": "Run these migrations: '{dependencies_id}', before migration {id}.",
|
||||||
"migrations_failed_to_load_migration": "Could not load migration {id}: {error}",
|
"migrations_failed_to_load_migration": "Could not load migration {id}: {error}",
|
||||||
"migrations_exclusive_options": "'--auto', '--skip', and '--force-rerun' are mutually exclusive options.",
|
"migrations_exclusive_options": "'--auto', '--skip', and '--force-rerun' are mutually exclusive options.",
|
||||||
"migrations_list_conflict_pending_done": "You cannot use both '--previous' and '--done' at the same time.",
|
"migrations_list_conflict_pending_done": "You cannot use both '--previous' and '--done' at the same time.",
|
||||||
|
@ -365,73 +468,51 @@
|
||||||
"migrations_must_provide_explicit_targets": "You must provide explicit targets when using '--skip' or '--force-rerun'",
|
"migrations_must_provide_explicit_targets": "You must provide explicit targets when using '--skip' or '--force-rerun'",
|
||||||
"migrations_need_to_accept_disclaimer": "To run the migration {id}, your must accept the following disclaimer:\n---\n{disclaimer}\n---\nIf you accept to run the migration, please re-run the command with the option '--accept-disclaimer'.",
|
"migrations_need_to_accept_disclaimer": "To run the migration {id}, your must accept the following disclaimer:\n---\n{disclaimer}\n---\nIf you accept to run the migration, please re-run the command with the option '--accept-disclaimer'.",
|
||||||
"migrations_no_migrations_to_run": "No migrations to run",
|
"migrations_no_migrations_to_run": "No migrations to run",
|
||||||
"migrations_no_such_migration": "There is no migration called {id}",
|
"migrations_no_such_migration": "There is no migration called '{id}'",
|
||||||
"migrations_not_pending_cant_skip": "Those migrations are not pending, so cannot be skipped: {ids}",
|
"migrations_not_pending_cant_skip": "Those migrations are not pending, so cannot be skipped: {ids}",
|
||||||
"migrations_pending_cant_rerun": "Those migrations are still pending, so cannot be run again: {ids}",
|
"migrations_pending_cant_rerun": "Those migrations are still pending, so cannot be run again: {ids}",
|
||||||
"migrations_running_forward": "Running migration {id}…",
|
"migrations_running_forward": "Running migration {id}…",
|
||||||
"migrations_skip_migration": "Skipping migration {id}…",
|
"migrations_skip_migration": "Skipping migration {id}…",
|
||||||
"migrations_success_forward": "Migration {id} completed",
|
"migrations_success_forward": "Migration {id} completed",
|
||||||
"migrations_to_be_ran_manually": "Migration {id} has to be run manually. Please go to Tools → Migrations on the webadmin page, or run `yunohost tools migrations migrate`.",
|
"migrations_to_be_ran_manually": "Migration {id} has to be run manually. Please go to Tools → Migrations on the webadmin page, or run `yunohost tools migrations migrate`.",
|
||||||
"monitor_disabled": "Server monitoring now turned off",
|
"no_internet_connection": "The server is not connected to the Internet",
|
||||||
"monitor_enabled": "Server monitoring now turned on",
|
|
||||||
"monitor_glances_con_failed": "Could not connect to Glances server",
|
|
||||||
"monitor_not_enabled": "Server monitoring is off",
|
|
||||||
"monitor_period_invalid": "Invalid time period",
|
|
||||||
"monitor_stats_file_not_found": "Statistics file not found",
|
|
||||||
"monitor_stats_no_update": "No monitoring statistics to update",
|
|
||||||
"monitor_stats_period_unavailable": "No available statistics for the period",
|
|
||||||
"mountpoint_unknown": "Unknown mountpoint",
|
|
||||||
"mysql_db_creation_failed": "MySQL database creation failed",
|
|
||||||
"mysql_db_init_failed": "MySQL database init failed",
|
|
||||||
"mysql_db_initialized": "The MySQL database now initialized",
|
|
||||||
"need_define_permission_before": "Redefine the permission using 'yunohost user permission add -u USER' before removing an allowed group",
|
|
||||||
"network_check_mx_ko": "DNS MX record is not set",
|
|
||||||
"network_check_smtp_ko": "Outbound e-mail (SMTP port 25) seems to be blocked by your network",
|
|
||||||
"network_check_smtp_ok": "Outbound e-mail (SMTP port 25) is not blocked",
|
|
||||||
"no_internet_connection": "Server not connected to the Internet",
|
|
||||||
"not_enough_disk_space": "Not enough free space on '{path:s}'",
|
"not_enough_disk_space": "Not enough free space on '{path:s}'",
|
||||||
"operation_interrupted": "The operation was manually interrupted?",
|
"operation_interrupted": "The operation was manually interrupted?",
|
||||||
"package_not_installed": "Package '{pkgname}' is not installed",
|
|
||||||
"package_unexpected_error": "An unexpected error occurred processing the package '{pkgname}'",
|
|
||||||
"package_unknown": "Unknown package '{pkgname}'",
|
"package_unknown": "Unknown package '{pkgname}'",
|
||||||
"packages_upgrade_failed": "Could not upgrade all the packages",
|
"packages_upgrade_failed": "Could not upgrade all the packages",
|
||||||
"password_listed": "This password is among the most used password in the world. Please choose something more unique.",
|
"password_listed": "This password is among the most used passwords in the world. Please choose something more unique.",
|
||||||
"password_too_simple_1": "The password needs to be at least 8 characters long",
|
"password_too_simple_1": "The password needs to be at least 8 characters long",
|
||||||
"password_too_simple_2": "The password needs to be at least 8 characters long and contain a digit, upper and lower characters",
|
"password_too_simple_2": "The password needs to be at least 8 characters long and contain a digit, upper and lower characters",
|
||||||
"password_too_simple_3": "The password needs to be at least 8 characters long and contain a digit, upper, lower and special characters",
|
"password_too_simple_3": "The password needs to be at least 8 characters long and contain a digit, upper, lower and special characters",
|
||||||
"password_too_simple_4": "The password needs to be at least 12 characters long and contain a digit, upper, lower and special characters",
|
"password_too_simple_4": "The password needs to be at least 12 characters long and contain a digit, upper, lower and special characters",
|
||||||
"pattern_backup_archive_name": "Must be a valid filename with max 30 characters, alphanumeric and -_. characters only",
|
"pattern_backup_archive_name": "Must be a valid filename with max 30 characters, alphanumeric and -_. characters only",
|
||||||
"pattern_domain": "Must be a valid domain name (e.g. my-domain.org)",
|
"pattern_domain": "Must be a valid domain name (e.g. my-domain.org)",
|
||||||
"pattern_email": "Must be a valid email address (e.g. someone@domain.org)",
|
"pattern_email": "Must be a valid e-mail address (e.g. someone@example.com)",
|
||||||
"pattern_firstname": "Must be a valid first name",
|
"pattern_firstname": "Must be a valid first name",
|
||||||
"pattern_lastname": "Must be a valid last name",
|
"pattern_lastname": "Must be a valid last name",
|
||||||
"pattern_listname": "Must be alphanumeric and underscore characters only",
|
|
||||||
"pattern_mailbox_quota": "Must be a size with b/k/M/G/T suffix or 0 to not have a quota",
|
"pattern_mailbox_quota": "Must be a size with b/k/M/G/T suffix or 0 to not have a quota",
|
||||||
"pattern_password": "Must be at least 3 characters long",
|
"pattern_password": "Must be at least 3 characters long",
|
||||||
"pattern_port": "Must be a valid port number (i.e. 0-65535)",
|
|
||||||
"pattern_port_or_range": "Must be a valid port number (i.e. 0-65535) or range of ports (e.g. 100:200)",
|
"pattern_port_or_range": "Must be a valid port number (i.e. 0-65535) or range of ports (e.g. 100:200)",
|
||||||
"pattern_positive_number": "Must be a positive number",
|
"pattern_positive_number": "Must be a positive number",
|
||||||
"pattern_username": "Must be lower-case alphanumeric and underscore characters only",
|
"pattern_username": "Must be lower-case alphanumeric and underscore characters only",
|
||||||
"pattern_password_app": "Sorry, passwords can not contain the following characters: {forbidden_chars}",
|
"pattern_password_app": "Sorry, passwords can not contain the following characters: {forbidden_chars}",
|
||||||
"permission_already_clear": "Permission '{permission:s}' already clear for app {app:s}",
|
"permission_already_allowed": "Group '{group}' already has permission '{permission}' enabled",
|
||||||
"permission_already_exist": "Permission '{permission:s}' for app {app:s} already exist",
|
"permission_already_disallowed": "Group '{group}' already has permission '{permission}' disabled",
|
||||||
"permission_created": "Permission '{permission:s}' for app {app:s} created",
|
"permission_already_exist": "Permission '{permission}' already exists",
|
||||||
"permission_creation_failed": "Could not grant permission",
|
"permission_already_up_to_date": "The permission was not updated because the addition/removal requests already match the current state.",
|
||||||
"permission_deleted": "Permission '{permission:s}' for app {app:s} deleted",
|
"permission_cannot_remove_main": "Removing a main permission is not allowed",
|
||||||
"permission_deletion_failed": "Missing permission '{permission:s}' to delete the app '{app:s}'",
|
"permission_created": "Permission '{permission:s}' created",
|
||||||
"permission_not_found": "Permission '{permission:s}' not found for the application '{app:s}'",
|
"permission_creation_failed": "Could not create permission '{permission}': {error}",
|
||||||
"permission_name_not_valid": "Pick an allowed permission name for '{permission:s}'",
|
"permission_currently_allowed_for_all_users": "This permission is currently granted to all users in addition to other groups. You probably want to either remove the 'all_users' permission or remove the other groups it is currently granted to.",
|
||||||
"permission_update_failed": "Could not update permission",
|
"permission_deleted": "Permission '{permission:s}' deleted",
|
||||||
"permission_generated": "Permission database updated",
|
"permission_deletion_failed": "Could not delete permission '{permission}': {error}",
|
||||||
"permission_updated": "Permission '{permission:s}' for the app '{app:s}' updated",
|
"permission_not_found": "Permission '{permission:s}' not found",
|
||||||
|
"permission_update_failed": "Could not update permission '{permission}': {error}",
|
||||||
|
"permission_updated": "Permission '{permission:s}' updated",
|
||||||
"permission_update_nothing_to_do": "No permissions to update",
|
"permission_update_nothing_to_do": "No permissions to update",
|
||||||
|
"permission_require_account": "Permission {permission} only makes sense for users having an account, and therefore cannot be enabled for visitors.",
|
||||||
"port_already_closed": "Port {port:d} is already closed for {ip_version:s} connections",
|
"port_already_closed": "Port {port:d} is already closed for {ip_version:s} connections",
|
||||||
"port_already_opened": "Port {port:d} is already opened for {ip_version:s} connections",
|
"port_already_opened": "Port {port:d} is already opened for {ip_version:s} connections",
|
||||||
"port_available": "Port {port:d} is available",
|
|
||||||
"port_unavailable": "Port {port:d} is not available",
|
|
||||||
"recommend_to_add_first_user": "The post-install is finished, but YunoHost needs at least one user to work correctly, you should add one using 'yunohost user create <username>' or do it from the admin interface.",
|
|
||||||
"remove_main_permission_not_allowed": "Removing the main permission is not allowed",
|
|
||||||
"remove_user_of_group_not_allowed": "You are not allowed to remove the user '{user:s}' in the group '{group:s}'",
|
|
||||||
"regenconf_file_backed_up": "Configuration file '{conf}' backed up to '{backup}'",
|
"regenconf_file_backed_up": "Configuration file '{conf}' backed up to '{backup}'",
|
||||||
"regenconf_file_copy_failed": "Could not copy the new configuration file '{new}' to '{conf}'",
|
"regenconf_file_copy_failed": "Could not copy the new configuration file '{new}' to '{conf}'",
|
||||||
"regenconf_file_kept_back": "The configuration file '{conf}' is expected to be deleted by regen-conf (category {category}) but was kept back.",
|
"regenconf_file_kept_back": "The configuration file '{conf}' is expected to be deleted by regen-conf (category {category}) but was kept back.",
|
||||||
|
@ -442,7 +523,7 @@
|
||||||
"regenconf_file_updated": "Configuration file '{conf}' updated",
|
"regenconf_file_updated": "Configuration file '{conf}' updated",
|
||||||
"regenconf_now_managed_by_yunohost": "The configuration file '{conf}' is now managed by YunoHost (category {category}).",
|
"regenconf_now_managed_by_yunohost": "The configuration file '{conf}' is now managed by YunoHost (category {category}).",
|
||||||
"regenconf_up_to_date": "The configuration is already up-to-date for category '{category}'",
|
"regenconf_up_to_date": "The configuration is already up-to-date for category '{category}'",
|
||||||
"regenconf_updated": "Configuration for category '{category}' updated",
|
"regenconf_updated": "Configuration updated for '{category}'",
|
||||||
"regenconf_would_be_updated": "The configuration would have been updated for category '{category}'",
|
"regenconf_would_be_updated": "The configuration would have been updated for category '{category}'",
|
||||||
"regenconf_dry_pending_applying": "Checking pending configuration which would have been applied for category '{category}'…",
|
"regenconf_dry_pending_applying": "Checking pending configuration which would have been applied for category '{category}'…",
|
||||||
"regenconf_failed": "Could not regenerate the configuration for category(s): {categories}",
|
"regenconf_failed": "Could not regenerate the configuration for category(s): {categories}",
|
||||||
|
@ -454,8 +535,8 @@
|
||||||
"restore_confirm_yunohost_installed": "Do you really want to restore an already installed system? [{answers:s}]",
|
"restore_confirm_yunohost_installed": "Do you really want to restore an already installed system? [{answers:s}]",
|
||||||
"restore_extracting": "Extracting needed files from the archive…",
|
"restore_extracting": "Extracting needed files from the archive…",
|
||||||
"restore_failed": "Could not restore system",
|
"restore_failed": "Could not restore system",
|
||||||
"restore_hook_unavailable": "The restoration script for '{part:s}' not available on your system and not in the archive either",
|
"restore_hook_unavailable": "Restoration script for '{part:s}' not available on your system and not in the archive either",
|
||||||
"restore_may_be_not_enough_disk_space": "Your system seems does not have enough space (free: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)",
|
"restore_may_be_not_enough_disk_space": "Your system does not seem to have enough space (free: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)",
|
||||||
"restore_not_enough_disk_space": "Not enough space (space: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)",
|
"restore_not_enough_disk_space": "Not enough space (space: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)",
|
||||||
"restore_nothings_done": "Nothing was restored",
|
"restore_nothings_done": "Nothing was restored",
|
||||||
"restore_removing_tmp_dir_failed": "Could not remove an old temporary directory",
|
"restore_removing_tmp_dir_failed": "Could not remove an old temporary directory",
|
||||||
|
@ -469,96 +550,86 @@
|
||||||
"server_reboot": "The server will reboot",
|
"server_reboot": "The server will reboot",
|
||||||
"server_reboot_confirm": "The server will reboot immediatly, are you sure? [{answers:s}]",
|
"server_reboot_confirm": "The server will reboot immediatly, are you sure? [{answers:s}]",
|
||||||
"service_add_failed": "Could not add the service '{service:s}'",
|
"service_add_failed": "Could not add the service '{service:s}'",
|
||||||
"service_added": "The service '{service:s}' added",
|
"service_added": "The service '{service:s}' was added",
|
||||||
"service_already_started": "The service '{service:s}' has already been started",
|
"service_already_started": "The service '{service:s}' is running already",
|
||||||
"service_already_stopped": "The service '{service:s}' has already been stopped",
|
"service_already_stopped": "The service '{service:s}' has already been stopped",
|
||||||
"service_cmd_exec_failed": "Could not execute the command '{command:s}'",
|
"service_cmd_exec_failed": "Could not execute the command '{command:s}'",
|
||||||
"service_description_avahi-daemon": "Allows you to reach your server using 'yunohost.local' in your local network",
|
"service_description_avahi-daemon": "Allows you to reach your server using 'yunohost.local' in your local network",
|
||||||
"service_description_dnsmasq": "Handles domain name resolution (DNS)",
|
"service_description_dnsmasq": "Handles domain name resolution (DNS)",
|
||||||
"service_description_dovecot": "Allows e-mail clients to access/fetch email (via IMAP and POP3)",
|
"service_description_dovecot": "Allows e-mail clients to access/fetch email (via IMAP and POP3)",
|
||||||
"service_description_fail2ban": "Protects against brute-force and other kinds of attacks from the Internet",
|
"service_description_fail2ban": "Protects against brute-force and other kinds of attacks from the Internet",
|
||||||
"service_description_glances": "Monitors system info on your server",
|
|
||||||
"service_description_metronome": "Manage XMPP instant messaging accounts",
|
"service_description_metronome": "Manage XMPP instant messaging accounts",
|
||||||
"service_description_mysql": "Stores applications data (SQL database)",
|
"service_description_mysql": "Stores app data (SQL database)",
|
||||||
"service_description_nginx": "Serves or provides access to all the websites hosted on your server",
|
"service_description_nginx": "Serves or provides access to all the websites hosted on your server",
|
||||||
"service_description_nslcd": "Handles YunoHost user shell connection",
|
"service_description_nslcd": "Handles YunoHost user shell connection",
|
||||||
"service_description_php7.0-fpm": "Runs applications written in PHP with NGINX",
|
"service_description_php7.0-fpm": "Runs apps written in PHP with NGINX",
|
||||||
"service_description_postfix": "Used to send and receive e-mails",
|
"service_description_postfix": "Used to send and receive e-mails",
|
||||||
"service_description_redis-server": "A specialized database used for rapid data access, task queue, and communication between programs",
|
"service_description_redis-server": "A specialized database used for rapid data access, task queue, and communication between programs",
|
||||||
"service_description_rmilter": "Checks various parameters in e-mails",
|
|
||||||
"service_description_rspamd": "Filters spam, and other e-mail related features",
|
"service_description_rspamd": "Filters spam, and other e-mail related features",
|
||||||
"service_description_slapd": "Stores users, domains and related info",
|
"service_description_slapd": "Stores users, domains and related info",
|
||||||
"service_description_ssh": "Allows you to connect remotely to your server via a terminal (SSH protocol)",
|
"service_description_ssh": "Allows you to connect remotely to your server via a terminal (SSH protocol)",
|
||||||
"service_description_yunohost-api": "Manages interactions between the YunoHost web interface and the system",
|
"service_description_yunohost-api": "Manages interactions between the YunoHost web interface and the system",
|
||||||
"service_description_yunohost-firewall": "Manages open and close connexion ports to services",
|
"service_description_yunohost-firewall": "Manages open and close connection ports to services",
|
||||||
"service_disable_failed": "Could not turn off the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
"service_disable_failed": "Could not make the service '{service:s}' not start at boot.\n\nRecent service logs:{logs:s}",
|
||||||
"service_disabled": "'{service:s}' service turned off",
|
"service_disabled": "The service '{service:s}' will not be started anymore when system boots.",
|
||||||
"service_enable_failed": "Could not turn on the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
"service_enable_failed": "Could not make the service '{service:s}' automatically start at boot.\n\nRecent service logs:{logs:s}",
|
||||||
"service_enabled": "'{service:s}' service turned off",
|
"service_enabled": "The service '{service:s}' will now be automatically started during system boots.",
|
||||||
"service_no_log": "No log to display for service '{service:s}'",
|
|
||||||
"service_regen_conf_is_deprecated": "'yunohost service regen-conf' is deprecated! Please use 'yunohost tools regen-conf' instead.",
|
"service_regen_conf_is_deprecated": "'yunohost service regen-conf' is deprecated! Please use 'yunohost tools regen-conf' instead.",
|
||||||
"service_remove_failed": "Could not remove the service '{service:s}'",
|
"service_remove_failed": "Could not remove the service '{service:s}'",
|
||||||
"service_removed": "'{service:s}' service removed",
|
"service_removed": "Service '{service:s}' removed",
|
||||||
"service_reload_failed": "Could not reload the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
"service_reload_failed": "Could not reload the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
||||||
"service_reloaded": "'{service:s}' service reloaded",
|
"service_reloaded": "Service '{service:s}' reloaded",
|
||||||
"service_restart_failed": "Could not restart the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
"service_restart_failed": "Could not restart the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
||||||
"service_restarted": "'{service:s}' service restarted",
|
"service_restarted": "Service '{service:s}' restarted",
|
||||||
"service_reload_or_restart_failed": "Could not reload or restart the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
"service_reload_or_restart_failed": "Could not reload or restart the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
||||||
"service_reloaded_or_restarted": "'{service:s}' service reloaded or restarted",
|
"service_reloaded_or_restarted": "The service '{service:s}' was reloaded or restarted",
|
||||||
"service_start_failed": "Could not start the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
"service_start_failed": "Could not start the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
||||||
"service_started": "'{service:s}' service started",
|
"service_started": "Service '{service:s}' started",
|
||||||
"service_stop_failed": "Could not stop the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
"service_stop_failed": "Could not stop the service '{service:s}'\n\nRecent service logs:{logs:s}",
|
||||||
"service_stopped": "'{service:s}' service stopped",
|
"service_stopped": "Service '{service:s}' stopped",
|
||||||
"service_unknown": "Unknown service '{service:s}'",
|
"service_unknown": "Unknown service '{service:s}'",
|
||||||
"ssowat_conf_generated": "SSOwat configuration generated",
|
"ssowat_conf_generated": "SSOwat configuration generated",
|
||||||
"ssowat_conf_updated": "SSOwat configuration updated",
|
"ssowat_conf_updated": "SSOwat configuration updated",
|
||||||
"ssowat_persistent_conf_read_error": "Could not read persistent SSOwat configuration: {error:s}. Edit /etc/ssowat/conf.json.persistent file to fix the JSON syntax",
|
|
||||||
"ssowat_persistent_conf_write_error": "Could not save persistent SSOwat configuration: {error:s}. Edit /etc/ssowat/conf.json.persistent file to fix the JSON syntax",
|
|
||||||
"system_groupname_exists": "Groupname already exists in the system group",
|
|
||||||
"system_upgraded": "System upgraded",
|
"system_upgraded": "System upgraded",
|
||||||
"system_username_exists": "Username already exists in the list of system users",
|
"system_username_exists": "Username already exists in the list of system users",
|
||||||
"this_action_broke_dpkg": "This action broke dpkg/APT (the system package managers)… You can try to solve this issue by connecting through SSH and running `sudo dpkg --configure -a`.",
|
"this_action_broke_dpkg": "This action broke dpkg/APT (the system package managers)… You can try to solve this issue by connecting through SSH and running `sudo dpkg --configure -a`.",
|
||||||
"tools_update_failed_to_app_fetchlist": "Could not update YunoHost's applists because: {error}",
|
|
||||||
"tools_upgrade_at_least_one": "Please specify '--apps', or '--system'",
|
"tools_upgrade_at_least_one": "Please specify '--apps', or '--system'",
|
||||||
"tools_upgrade_cant_both": "Cannot upgrade both system and apps at the same time",
|
"tools_upgrade_cant_both": "Cannot upgrade both system and apps at the same time",
|
||||||
"tools_upgrade_cant_hold_critical_packages": "Could not hold critical packages…",
|
"tools_upgrade_cant_hold_critical_packages": "Could not hold critical packages…",
|
||||||
"tools_upgrade_cant_unhold_critical_packages": "Could not to unhold critical packages…",
|
"tools_upgrade_cant_unhold_critical_packages": "Could not unhold critical packages…",
|
||||||
"tools_upgrade_regular_packages": "Now upgrading 'regular' (non-yunohost-related) packages…",
|
"tools_upgrade_regular_packages": "Now upgrading 'regular' (non-yunohost-related) packages…",
|
||||||
"tools_upgrade_regular_packages_failed": "Could not upgrade packages: {packages_list}",
|
"tools_upgrade_regular_packages_failed": "Could not upgrade packages: {packages_list}",
|
||||||
"tools_upgrade_special_packages": "Now upgrading 'special' (yunohost-related) packages…",
|
"tools_upgrade_special_packages": "Now upgrading 'special' (yunohost-related) packages…",
|
||||||
"tools_upgrade_special_packages_explanation": "This action will end, but the actual special upgrade will continue in background. Please don't start any other action on your server in the next ~10 minutes (depending on your hardware speed). Once it i done, you may have to log in on the webadmin page again. The upgrade log will be available in Tools → Log (on the webadmin page) or through 'yunohost log list' (from the command line).",
|
"tools_upgrade_special_packages_explanation": "The special upgrade will continue in the background. Please don't start any other actions on your server for the next ~10 minutes (depending on hardware speed). After this, you may have to re-log in to the webadmin. The upgrade log will be available in Tools → Log (in the webadmin) or using 'yunohost log list' (from the command-line).",
|
||||||
"tools_upgrade_special_packages_completed": "YunoHost package upgrade completed.\nPress [Enter] to get the command line back",
|
"tools_upgrade_special_packages_completed": "YunoHost package upgrade completed.\nPress [Enter] to get the command line back",
|
||||||
"unbackup_app": "App '{app:s}' will not be saved",
|
"unbackup_app": "App '{app:s}' will not be saved",
|
||||||
"unexpected_error": "Something unexpected went wrong: {error}",
|
"unexpected_error": "Something unexpected went wrong: {error}",
|
||||||
"unit_unknown": "Unknown unit '{unit:s}'",
|
|
||||||
"unlimit": "No quota",
|
"unlimit": "No quota",
|
||||||
"unrestore_app": "App '{app:s}' will not be restored",
|
"unrestore_app": "App '{app:s}' will not be restored",
|
||||||
"update_apt_cache_failed": "Could not to update the cache of APT (Debian's package manager). Here is a dump of the sources.list lines, which might help identify problematic lines: \n{sourceslist}",
|
"update_apt_cache_failed": "Could not to update the cache of APT (Debian's package manager). Here is a dump of the sources.list lines, which might help identify problematic lines: \n{sourceslist}",
|
||||||
"update_apt_cache_warning": "Something went wrong while updating the cache of APT (Debian's package manager). Here is a dump of the sources.list lines, which might help identify problematic lines: \n{sourceslist}",
|
"update_apt_cache_warning": "Something went wrong while updating the cache of APT (Debian's package manager). Here is a dump of the sources.list lines, which might help identify problematic lines: \n{sourceslist}",
|
||||||
"updating_apt_cache": "Fetching available upgrades for system packages…",
|
"updating_apt_cache": "Fetching available upgrades for system packages…",
|
||||||
"updating_app_lists": "Fetching available upgrades for applications…",
|
|
||||||
"upgrade_complete": "Upgrade complete",
|
"upgrade_complete": "Upgrade complete",
|
||||||
"upgrading_packages": "Upgrading packages…",
|
"upgrading_packages": "Upgrading packages…",
|
||||||
"upnp_dev_not_found": "No UPnP device found",
|
"upnp_dev_not_found": "No UPnP device found",
|
||||||
"upnp_disabled": "UPnP turned off",
|
"upnp_disabled": "UPnP turned off",
|
||||||
"upnp_enabled": "UPnP turned on",
|
"upnp_enabled": "UPnP turned on",
|
||||||
"upnp_port_open_failed": "Could not open port via UPnP",
|
"upnp_port_open_failed": "Could not open port via UPnP",
|
||||||
"user_already_in_group": "The user '{user:}' is already in the '{group:s}' group",
|
"user_already_exists": "The user '{user}' already exists",
|
||||||
"user_created": "User created",
|
"user_created": "User created",
|
||||||
"user_creation_failed": "Could not create user",
|
"user_creation_failed": "Could not create user {user}: {error}",
|
||||||
"user_deleted": "User deleted",
|
"user_deleted": "User deleted",
|
||||||
"user_deletion_failed": "Could not delete user",
|
"user_deletion_failed": "Could not delete user {user}: {error}",
|
||||||
"user_home_creation_failed": "Could not create 'home' folder for user",
|
"user_home_creation_failed": "Could not create 'home' folder for user",
|
||||||
"user_info_failed": "Could not retrieve user info",
|
|
||||||
"user_not_in_group": "The user '{user:s}' is not in the group {group:s}",
|
|
||||||
"user_unknown": "Unknown user: {user:s}",
|
"user_unknown": "Unknown user: {user:s}",
|
||||||
"user_update_failed": "Could not change user info",
|
"user_update_failed": "Could not update user {user}: {error}",
|
||||||
"user_updated": "User info changed",
|
"user_updated": "User info changed",
|
||||||
"users_available": "Available users:",
|
"users_available": "Available users:",
|
||||||
"yunohost_already_installed": "YunoHost is already installed",
|
"yunohost_already_installed": "YunoHost is already installed",
|
||||||
"yunohost_ca_creation_failed": "Could not create certificate authority",
|
"yunohost_ca_creation_failed": "Could not create certificate authority",
|
||||||
"yunohost_ca_creation_success": "Local certification authority created.",
|
"yunohost_ca_creation_success": "Local certification authority created.",
|
||||||
"yunohost_configured": "YunoHost now configured",
|
"yunohost_configured": "YunoHost is now configured",
|
||||||
"yunohost_installing": "Installing YunoHost…",
|
"yunohost_installing": "Installing YunoHost…",
|
||||||
"yunohost_not_installed": "YunoHost is incorrectly or not correctly installed. Please run 'yunohost tools postinstall'"
|
"yunohost_not_installed": "YunoHost is not correctly installed. Please run 'yunohost tools postinstall'",
|
||||||
|
"yunohost_postinstall_end_tip": "The post-install completed! To finalize your setup, please consider:\n - adding a first user through the 'Users' section of the webadmin (or 'yunohost user create <username>' in command-line);\n - diagnose potential issues through the 'Diagnosis' section of the webadmin (or 'yunohost diagnosis run' in command-line);\n - reading the 'Finalizing your setup' and 'Getting to know Yunohost' parts in the admin documentation: https://yunohost.org/admindoc."
|
||||||
}
|
}
|
||||||
|
|
616
locales/eo.json
616
locales/eo.json
|
@ -1,43 +1,595 @@
|
||||||
{
|
{
|
||||||
"admin_password_change_failed": "Malebla ŝanĝi pasvorton",
|
"admin_password_change_failed": "Ne eblas ŝanĝi pasvorton",
|
||||||
"admin_password_changed": "Pasvorto de la estro estas ŝanĝita",
|
"admin_password_changed": "La pasvorto de administrado ŝanĝiĝis",
|
||||||
"app_already_installed": "{app:s} estas jam instalita",
|
"app_already_installed": "{app:s} estas jam instalita",
|
||||||
"app_already_up_to_date": "{app:s} estas ĝisdata",
|
"app_already_up_to_date": "{app:s} estas jam ĝisdata",
|
||||||
"app_argument_required": "Parametro {name:s} estas bezonata",
|
"app_argument_required": "Parametro {name:s} estas bezonata",
|
||||||
"app_change_url_identical_domains": "Malnovaj kaj novaj domajno/URL estas la sama ('{domain:s}{path:s}'), nenio fareblas.",
|
"app_change_url_identical_domains": "Malnovaj kaj novaj domajno/URL estas la sama ('{domain:s}{path:s}'), nenio fareblas.",
|
||||||
"app_change_url_success": "URL de appo {app:s} ŝanĝita al {domain:s}{path:s}",
|
"app_change_url_success": "{app:s} URL nun estas {domain:s} {path:s}",
|
||||||
"app_extraction_failed": "Malebla malkompaktigi instaldosierojn",
|
"app_extraction_failed": "Ne povis ĉerpi la instalajn dosierojn",
|
||||||
"app_id_invalid": "Nevalida apo id",
|
"app_id_invalid": "Nevalida apo ID",
|
||||||
"app_incompatible": "Apo {app} ne estas kongrua kun via YunoHost versio",
|
"app_install_files_invalid": "Ĉi tiuj dosieroj ne povas esti instalitaj",
|
||||||
"app_install_files_invalid": "Nevalidaj instaldosieroj",
|
"user_updated": "Uzantinformoj ŝanĝis",
|
||||||
"app_location_already_used": "Apo {app} jam estas instalita al tiu loco ({path})",
|
|
||||||
"user_updated": "Uzanto estas ĝisdatita",
|
|
||||||
"users_available": "Uzantoj disponeblaj :",
|
"users_available": "Uzantoj disponeblaj :",
|
||||||
"yunohost_already_installed": "YunoHost estas jam instalita",
|
"yunohost_already_installed": "YunoHost estas jam instalita",
|
||||||
"yunohost_ca_creation_failed": "Ne eblas krei atestan aŭtoritaton",
|
"yunohost_ca_creation_failed": "Ne povis krei atestan aŭtoritaton",
|
||||||
"yunohost_ca_creation_success": "Loka atesta aŭtoritato estas kreita.",
|
"yunohost_ca_creation_success": "Loka atestila aŭtoritato kreiĝis.",
|
||||||
"yunohost_installing": "Instalante YunoHost…",
|
"yunohost_installing": "Instalante YunoHost…",
|
||||||
"service_description_glances": "monitoras sisteminformojn de via servilo",
|
"service_description_metronome": "Mastrumas XMPP tujmesaĝilon kontojn",
|
||||||
"service_description_metronome": "mastrumas XMPP tujmesaĝilon kontojn",
|
"service_description_mysql": "Butikigas datumojn de programoj (SQL datumbazo)",
|
||||||
"service_description_mysql": "stokas aplikaĵojn datojn (SQL datumbazo)",
|
"service_description_nginx": "Servas aŭ permesas atingi ĉiujn retejojn gastigita sur via servilo",
|
||||||
"service_description_nginx": "servas aŭ permesas atingi ĉiujn retejojn gastigita sur via servilo",
|
"service_description_nslcd": "Mastrumas Yunohost uzantojn konektojn per komanda linio",
|
||||||
"service_description_nslcd": "mastrumas Yunohost uzantojn konektojn per komanda linio",
|
"service_description_php7.0-fpm": "Ekzekutas programojn skribitajn en PHP kun NGINX",
|
||||||
"service_description_php7.0-fpm": "rulas aplikaĵojn skibita en PHP kun nginx",
|
"service_description_postfix": "Uzita por sendi kaj ricevi retpoŝtojn",
|
||||||
"service_description_postfix": "uzita por sendi kaj ricevi retpoŝtojn",
|
"service_description_redis-server": "Specialita datumbazo uzita por rapida datumo atingo, atendovicoj kaj komunikadoj inter programoj",
|
||||||
"service_description_redis-server": "specialita datumbazo uzita por rapida datumo atingo, atendovicoj kaj komunikadoj inter programoj",
|
"service_description_rspamd": "Filtras trudmesaĝojn, kaj aliaj funkcioj rilate al retpoŝto",
|
||||||
"service_description_rmilter": "kontrolas diversajn parametrojn en retpoŝtoj",
|
"service_description_slapd": "Stokas uzantojn, domajnojn kaj rilatajn informojn",
|
||||||
"service_description_rspamd": "filtras trudmesaĝojn, kaj aliaj funkcioj rilate al retpoŝto",
|
"service_description_ssh": "Permesas al vi konekti al via servilo kun fora terminalo (SSH protokolo)",
|
||||||
"service_description_slapd": "stokas uzantojn, domajnojn kaj rilatajn informojn",
|
"service_description_yunohost-api": "Mastrumas interagojn inter la YunoHost retinterfaco kaj la sistemo",
|
||||||
"service_description_ssh": "permesas al vi konekti al via servilo kun fora terminalo (SSH protokolo)",
|
"service_description_yunohost-firewall": "Administras malfermajn kaj fermajn konektajn havenojn al servoj",
|
||||||
"service_description_yunohost-api": "mastrumas interagojn inter la YunoHost retinterfaco kaj la sistemo",
|
"service_disable_failed": "Ne povis fari la servon '{service:s}' ne komenci ĉe la ekkuro.\n\nLastatempaj servaj protokoloj: {logs:s}",
|
||||||
"service_description_yunohost-firewall": "mastrumas malfermitajn kaj fermitajn konektejojn al servoj",
|
"service_disabled": "La servo '{service:s}' ne plu komenciĝos kiam sistemo ekos.",
|
||||||
"service_disable_failed": "Neebla malaktivigi servon '{service:s}'\n\nFreŝaj protokoloj de la servo : {logs:s}",
|
|
||||||
"service_disabled": "Servo '{service:s}' estas malaktivigita",
|
|
||||||
"action_invalid": "Nevalida ago « {action:s} »",
|
"action_invalid": "Nevalida ago « {action:s} »",
|
||||||
"admin_password": "Pasvorto de la estro",
|
"admin_password": "Pasvorto de la estro",
|
||||||
"admin_password_too_long": "Bonvolu elekti pasvorton pli mallonga ol 127 signoj",
|
"admin_password_too_long": "Bonvolu elekti pasvorton pli mallonga ol 127 signoj",
|
||||||
"already_up_to_date": "Neniu estas farenda! Ĉiu jam estas ĝisdata!",
|
"already_up_to_date": "Nenio por fari. Ĉio estas jam ĝisdatigita.",
|
||||||
"app_argument_choice_invalid": "Nevalida elekto por argumento « {name:s} », ĝi devas esti unu el {choices:s}",
|
"app_argument_choice_invalid": "Uzu unu el ĉi tiuj elektoj '{choices:s}' por la argumento '{name:s}'",
|
||||||
"app_argument_invalid": "Nevalida valoro por argumento « {name:s} » : {error:s}",
|
"app_argument_invalid": "Elektu validan valoron por la argumento '{name:s}': {error:s}",
|
||||||
"app_change_url_failed_nginx_reload": "Reŝargi nginx malsuksesis. Jen la eligo de « nginx -t » :\n{nginx_errors:s}"
|
"app_change_url_failed_nginx_reload": "Ne eblis reŝarĝi NGINX. Jen la eligo de 'nginx -t':\n{nginx_errors:s}",
|
||||||
|
"ask_new_admin_password": "Nova administrada pasvorto",
|
||||||
|
"app_action_broke_system": "Ĉi tiu ago ŝajne rompis ĉi tiujn gravajn servojn: {services}",
|
||||||
|
"app_unsupported_remote_type": "Malkontrolita fora speco uzita por la apliko",
|
||||||
|
"backup_archive_system_part_not_available": "Sistemo parto '{part:s}' ne haveblas en ĉi tiu rezervo",
|
||||||
|
"backup_abstract_method": "Ĉi tiu rezerva metodo ankoraŭ efektiviĝis",
|
||||||
|
"apps_already_up_to_date": "Ĉiuj aplikoj estas jam ĝisdatigitaj",
|
||||||
|
"backup_borg_not_implemented": "La kopia metodo de Borg ankoraŭ ne estas efektivigita",
|
||||||
|
"app_location_unavailable": "Ĉi tiu URL aŭ ne haveblas, aŭ konfliktas kun la jam instalita (j) apliko (j):\n{apps:s}",
|
||||||
|
"backup_archive_app_not_found": "Ne povis trovi la programon '{app:s}' en la rezerva ar archiveivo",
|
||||||
|
"backup_actually_backuping": "Krei rezervan ar archiveivon el la kolektitaj dosieroj …",
|
||||||
|
"backup_method_borg_finished": "Sekurkopio en Borg finiĝis",
|
||||||
|
"app_change_url_no_script": "La app '{app_name:s}' ankoraŭ ne subtenas URL-modifon. Eble vi devus altgradigi ĝin.",
|
||||||
|
"app_start_install": "Instali la programon '{app}' …",
|
||||||
|
"backup_created": "Sekurkopio kreita",
|
||||||
|
"app_make_default_location_already_used": "Ne povas igi la aplikon '{app}' defaŭlta sur la domajno, '{domain}' jam uziĝas de la alia app '{other_app}'",
|
||||||
|
"backup_method_copy_finished": "Rezerva kopio finis",
|
||||||
|
"app_not_properly_removed": "{app:s} ne estis ĝuste forigita",
|
||||||
|
"backup_archive_broken_link": "Ne povis aliri la rezervan ar archiveivon (rompita ligilo al {path:s})",
|
||||||
|
"app_requirements_checking": "Kontrolante postulatajn pakaĵojn por {app} …",
|
||||||
|
"app_not_installed": "Ne povis trovi la aplikon '{app:s}' en la listo de instalitaj programoj: {all_apps}",
|
||||||
|
"ask_new_path": "Nova vojo",
|
||||||
|
"backup_custom_mount_error": "Propra rezerva metodo ne povis preterpasi la paŝon 'monto'",
|
||||||
|
"app_upgrade_app_name": "Nun ĝisdatiganta {app} …",
|
||||||
|
"app_manifest_invalid": "Io misas pri la aplika manifesto: {error}",
|
||||||
|
"backup_cleaning_failed": "Ne povis purigi la provizoran rezervan dosierujon",
|
||||||
|
"backup_invalid_archive": "Ĉi tio ne estas rezerva ar archiveivo",
|
||||||
|
"backup_creation_failed": "Ne povis krei la rezervan ar archiveivon",
|
||||||
|
"backup_hook_unknown": "La rezerva hoko '{hook:s}' estas nekonata",
|
||||||
|
"backup_custom_backup_error": "Propra rezerva metodo ne povis preterpasi la paŝon \"sekurkopio\"",
|
||||||
|
"ask_main_domain": "Ĉefa domajno",
|
||||||
|
"backup_method_tar_finished": "TAR-rezerva ar archiveivo kreita",
|
||||||
|
"backup_cant_mount_uncompress_archive": "Ne povis munti la nekompresitan ar archiveivon kiel protektita kontraŭ skribo",
|
||||||
|
"app_action_cannot_be_ran_because_required_services_down": "Ĉi tiuj postulataj servoj devas funkcii por funkciigi ĉi tiun agon: {services}. Provu rekomenci ilin por daŭrigi (kaj eble esploru, kial ili malsupreniras).",
|
||||||
|
"backup_copying_to_organize_the_archive": "Kopiante {size:s} MB por organizi la ar archiveivon",
|
||||||
|
"backup_output_directory_forbidden": "Elektu malsaman elirejan dosierujon. Sekurkopioj ne povas esti kreitaj en sub-dosierujoj / bin, / boot, / dev, / ktp, / lib, / root, / run, / sbin, / sys, / usr, / var aŭ /home/yunohost.backup/archives",
|
||||||
|
"backup_no_uncompress_archive_dir": "Ne ekzistas tia nekompremita arkiva dosierujo",
|
||||||
|
"password_too_simple_1": "Pasvorto devas esti almenaŭ 8 signojn longa",
|
||||||
|
"app_upgrade_failed": "Ne povis ĝisdatigi {app:s}: {error}",
|
||||||
|
"app_upgrade_several_apps": "La sekvaj apliko estos altgradigitaj: {apps}",
|
||||||
|
"backup_archive_open_failed": "Ne povis malfermi la rezervan ar archiveivon",
|
||||||
|
"ask_lastname": "Familia nomo",
|
||||||
|
"app_start_backup": "Kolekti dosierojn por esti subtenata por la '{app}' …",
|
||||||
|
"backup_archive_name_exists": "Rezerva arkivo kun ĉi tiu nomo jam ekzistas.",
|
||||||
|
"backup_applying_method_tar": "Krei la rezervan TAR-ar archiveivon …",
|
||||||
|
"backup_method_custom_finished": "Propra rezerva metodo '{method:s}' finiĝis",
|
||||||
|
"app_already_installed_cant_change_url": "Ĉi tiu app estas jam instalita. La URL ne povas esti ŝanĝita nur per ĉi tiu funkcio. Rigardu \"app changeurl\" se ĝi haveblas.",
|
||||||
|
"app_not_correctly_installed": "{app:s} ŝajnas esti malĝuste instalita",
|
||||||
|
"app_removed": "{app:s} forigita",
|
||||||
|
"backup_delete_error": "Ne povis forigi '{path:s}'",
|
||||||
|
"backup_nothings_done": "Nenio por ŝpari",
|
||||||
|
"backup_applying_method_custom": "Nomante la kutiman rezervan metodon '{method:s}' …",
|
||||||
|
"backup_app_failed": "Ne eblis rezervi la programon '{app:s}'",
|
||||||
|
"app_upgrade_some_app_failed": "Iuj aplikoj ne povis esti altgradigitaj",
|
||||||
|
"app_start_remove": "Forigo de la apliko '{app}' …",
|
||||||
|
"backup_output_directory_not_empty": "Vi devas elekti malplenan eligitan dosierujon",
|
||||||
|
"backup_archive_writing_error": "Ne povis aldoni la dosierojn '{source:s}' (nomitaj en la ar theivo '{dest:s}') por esti rezervitaj en la kunpremita arkivo '{archive:s}'",
|
||||||
|
"ask_email": "Retpoŝta adreso",
|
||||||
|
"app_start_restore": "Restarigi la programon '{app}' …",
|
||||||
|
"backup_applying_method_copy": "Kopiante ĉiujn dosierojn al sekurkopio …",
|
||||||
|
"backup_couldnt_bind": "Ne povis ligi {src:s} al {dest:s}.",
|
||||||
|
"ask_password": "Pasvorto",
|
||||||
|
"app_requirements_unmeet": "Postuloj ne estas renkontitaj por {app}, la pakaĵo {pkgname} ({version}) devas esti {spec}",
|
||||||
|
"ask_firstname": "Antaŭnomo",
|
||||||
|
"backup_ask_for_copying_if_needed": "Ĉu vi volas realigi la sekurkopion uzante {size:s} MB provizore? (Ĉi tiu maniero estas uzata ĉar iuj dosieroj ne povus esti pretigitaj per pli efika metodo.)",
|
||||||
|
"backup_mount_archive_for_restore": "Preparante arkivon por restarigo …",
|
||||||
|
"backup_csv_creation_failed": "Ne povis krei la CSV-dosieron bezonatan por restarigo",
|
||||||
|
"backup_archive_name_unknown": "Nekonata loka rezerva ar archiveivo nomata '{name:s}'",
|
||||||
|
"backup_applying_method_borg": "Sendado de ĉiuj dosieroj al sekurkopio en borg-rezerva deponejo …",
|
||||||
|
"app_sources_fetch_failed": "Ne povis akiri fontajn dosierojn, ĉu la URL estas ĝusta?",
|
||||||
|
"ask_new_domain": "Nova domajno",
|
||||||
|
"app_unknown": "Nekonata apliko",
|
||||||
|
"app_not_upgraded": "La aplikaĵo '{failed_app}' ne ĝisdatigis, kaj pro tio la sekvaj ĝisdatigoj de aplikoj estis nuligitaj: {apps}",
|
||||||
|
"aborting": "Aborti.",
|
||||||
|
"app_upgraded": "{app:s} altgradigita",
|
||||||
|
"backup_deleted": "Rezerva forigita",
|
||||||
|
"backup_csv_addition_failed": "Ne povis aldoni dosierojn al sekurkopio en la CSV-dosiero",
|
||||||
|
"dpkg_lock_not_available": "Ĉi tiu komando ne povas funkcii nun ĉar alia programo uzas la seruron de dpkg (la administrilo de paka sistemo)",
|
||||||
|
"migration_0003_yunohost_upgrade": "Komenci la ĝisdatigon de YunoHost-pako ... La migrado finiĝos, sed la efektiva ĝisdatigo okazos tuj poste. Post kiam la operacio finiĝos, vi eble devos ensaluti denove sur la retpaĝo.",
|
||||||
|
"domain_dyndns_root_unknown": "Nekonata radika domajno DynDNS",
|
||||||
|
"field_invalid": "Nevalida kampo '{:s}'",
|
||||||
|
"log_app_makedefault": "Faru '{}' la defaŭlta apliko",
|
||||||
|
"migration_0003_still_on_jessie_after_main_upgrade": "Io okazis malbone dum la ĉefa ĝisdatigo: Ĉu la sistemo ankoraŭ estas en Jessie‽ Por esplori la aferon, bonvolu rigardi {log}:s …",
|
||||||
|
"migration_0011_can_not_backup_before_migration": "La sekurkopio de la sistemo ne povis finiĝi antaŭ ol la migrado malsukcesis. Eraro: {error:s}",
|
||||||
|
"migration_0011_create_group": "Krei grupon por ĉiu uzanto…",
|
||||||
|
"backup_system_part_failed": "Ne eblis sekurkopi la sistemon de '{part:s}'",
|
||||||
|
"global_settings_setting_security_postfix_compatibility": "Kongruo vs sekureca kompromiso por la Postfix-servilo. Afektas la ĉifradojn (kaj aliajn aspektojn pri sekureco)",
|
||||||
|
"group_unknown": "La grupo '{group:s}' estas nekonata",
|
||||||
|
"mailbox_disabled": "Retpoŝto malŝaltita por uzanto {user:s}",
|
||||||
|
"migration_description_0011_setup_group_permission": "Agordu uzantogrupon kaj starigu permeson por programoj kaj servoj",
|
||||||
|
"migration_0011_backup_before_migration": "Krei sekurkopion de LDAP-datumbazo kaj agordojn antaŭ la efektiva migrado.",
|
||||||
|
"migration_0011_migrate_permission": "Migrado de permesoj de agordoj al aplikoj al LDAP…",
|
||||||
|
"migration_0011_migration_failed_trying_to_rollback": "Ne povis migri ... provante redakti la sistemon.",
|
||||||
|
"migrations_dependencies_not_satisfied": "Rulu ĉi tiujn migradojn: '{dependencies_id}', antaŭ migrado {id}.",
|
||||||
|
"migrations_failed_to_load_migration": "Ne povis ŝarĝi migradon {id}: {error}",
|
||||||
|
"migrations_exclusive_options": "'--auto', '--skip' kaj '--force-rerun' estas reciproke ekskluzivaj ebloj.",
|
||||||
|
"migrations_must_provide_explicit_targets": "Vi devas provizi eksplicitajn celojn kiam vi uzas '--skip' aŭ '--force-rerun'",
|
||||||
|
"permission_update_failed": "Ne povis ĝisdatigi permeson '{permission}': {error}",
|
||||||
|
"permission_updated": "Ĝisdatigita \"{permission:s}\" rajtigita",
|
||||||
|
"permission_update_nothing_to_do": "Neniuj permesoj ĝisdatigi",
|
||||||
|
"tools_upgrade_cant_hold_critical_packages": "Ne povis teni kritikajn pakojn…",
|
||||||
|
"upnp_dev_not_found": "Neniu UPnP-aparato trovita",
|
||||||
|
"migration_description_0012_postgresql_password_to_md5_authentication": "Devigu PostgreSQL-aŭtentigon uzi MD5 por lokaj ligoj",
|
||||||
|
"migration_0011_done": "Migrado finiĝis. Vi nun kapablas administri uzantajn grupojn.",
|
||||||
|
"migration_0011_LDAP_update_failed": "Ne povis ĝisdatigi LDAP. Eraro: {error:s}",
|
||||||
|
"pattern_password": "Devas esti almenaŭ 3 signoj longaj",
|
||||||
|
"root_password_desynchronized": "La pasvorta administranto estis ŝanĝita, sed YunoHost ne povis propagandi ĉi tion al la radika pasvorto!",
|
||||||
|
"service_remove_failed": "Ne povis forigi la servon '{service:s}'",
|
||||||
|
"migration_0003_fail2ban_upgrade": "Komenci la ĝisdatigon Fail2Ban…",
|
||||||
|
"backup_permission": "Rezerva permeso por app {app:s}",
|
||||||
|
"log_user_group_delete": "Forigi grupon '{}'",
|
||||||
|
"log_user_group_update": "Ĝisdatigi grupon '{}'",
|
||||||
|
"migration_0005_postgresql_94_not_installed": "PostgreSQL ne estis instalita en via sistemo. Nenio por fari.",
|
||||||
|
"dyndns_provider_unreachable": "Ne povas atingi Dyndns-provizanton {provider}: ĉu via YunoHost ne estas ĝuste konektita al la interreto aŭ la dynette-servilo malŝaltiĝas.",
|
||||||
|
"good_practices_about_user_password": "Vi nun estas por difini novan uzantan pasvorton. La pasvorto devas esti almenaŭ 8 signoj - kvankam estas bone praktiki uzi pli longan pasvorton (t.e. pasfrazon) kaj / aŭ variaĵon de signoj (majuskloj, minuskloj, ciferoj kaj specialaj signoj).",
|
||||||
|
"group_updated": "Ĝisdatigita \"{group}\" grupo",
|
||||||
|
"group_already_exist": "Grupo {group} jam ekzistas",
|
||||||
|
"group_already_exist_on_system": "Grupo {group} jam ekzistas en la sistemaj grupoj",
|
||||||
|
"group_cannot_be_deleted": "La grupo {group} ne povas esti forigita permane.",
|
||||||
|
"group_update_failed": "Ne povis ĝisdatigi la grupon '{group}': {error}",
|
||||||
|
"group_user_already_in_group": "Uzanto {user} jam estas en grupo {group}",
|
||||||
|
"group_user_not_in_group": "Uzanto {user} ne estas en grupo {group}",
|
||||||
|
"installation_complete": "Kompleta instalado",
|
||||||
|
"log_category_404": "La loga kategorio '{category}' ne ekzistas",
|
||||||
|
"log_permission_create": "Krei permeson '{}'",
|
||||||
|
"log_permission_delete": "Forigi permeson '{}'",
|
||||||
|
"log_user_group_create": "Krei grupon '{}'",
|
||||||
|
"log_user_permission_update": "Mise à jour des accès pour la permission '{}'",
|
||||||
|
"log_user_permission_reset": "Restarigi permeson '{}'",
|
||||||
|
"mail_forward_remove_failed": "Ne povis forigi retpoŝton plusendante '{mail:s}'",
|
||||||
|
"migration_0011_rollback_success": "Sistemo ruliĝis reen.",
|
||||||
|
"migration_0011_update_LDAP_database": "Ĝisdatigante LDAP-datumbazon…",
|
||||||
|
"migration_0011_update_LDAP_schema": "Ĝisdatigante LDAP-skemon…",
|
||||||
|
"migration_0011_failed_to_remove_stale_object": "Ne povis forigi neuzatan objekton {dn}: {error}",
|
||||||
|
"migrations_already_ran": "Tiuj migradoj estas jam faritaj: {ids}",
|
||||||
|
"migrations_no_such_migration": "Estas neniu migrado nomata '{id}'",
|
||||||
|
"permission_already_allowed": "Grupo '{group}' jam havas rajtigitan permeson '{permission}'",
|
||||||
|
"permission_already_disallowed": "Grupo '{group}' jam havas permeson '{permission}' malebligita'",
|
||||||
|
"permission_cannot_remove_main": "Forigo de ĉefa permeso ne rajtas",
|
||||||
|
"permission_creation_failed": "Ne povis krei permeson '{permission}': {error}",
|
||||||
|
"user_already_exists": "La uzanto '{user}' jam ekzistas",
|
||||||
|
"migrations_pending_cant_rerun": "Tiuj migradoj ankoraŭ estas pritraktataj, do ne plu rajtas esti ekzekutitaj: {ids}",
|
||||||
|
"migrations_running_forward": "Kuranta migrado {id}…",
|
||||||
|
"migrations_success_forward": "Migrado {id} kompletigita",
|
||||||
|
"operation_interrupted": "La operacio estis permane interrompita?",
|
||||||
|
"permission_created": "Permesita '{permission:s}' kreita",
|
||||||
|
"permission_deleted": "Permesita \"{permission:s}\" forigita",
|
||||||
|
"permission_deletion_failed": "Ne povis forigi permeson '{permission}': {error}",
|
||||||
|
"permission_not_found": "Permesita \"{permission:s}\" ne trovita",
|
||||||
|
"restore_not_enough_disk_space": "Ne sufiĉa spaco (spaco: {free_space:d} B, necesa spaco: {needed_space:d} B, sekureca marĝeno: {margin:d} B)",
|
||||||
|
"tools_upgrade_regular_packages": "Nun ĝisdatigi 'regulajn' (ne-yunohost-rilatajn) pakojn …",
|
||||||
|
"tools_upgrade_special_packages_explanation": "La speciala ĝisdatigo daŭros en fono. Bonvolu ne komenci aliajn agojn en via servilo la sekvajn ~ 10 minutojn (depende de la aparata rapideco). Post tio, vi eble devos re-ensaluti sur la retadreso. La ĝisdatiga registro estos havebla en Iloj → Ensaluto (en la retadreso) aŭ uzante 'yunohost-logliston' (el la komandlinio).",
|
||||||
|
"unrestore_app": "App '{app:s}' ne restarigos",
|
||||||
|
"group_created": "Grupo '{group}' kreita",
|
||||||
|
"group_creation_failed": "Ne povis krei la grupon '{group}': {error}",
|
||||||
|
"group_deleted": "Grupo '{group}' forigita",
|
||||||
|
"group_deletion_failed": "Ne povis forigi la grupon '{group}': {error}",
|
||||||
|
"migrations_not_pending_cant_skip": "Tiuj migradoj ankoraŭ ne estas pritraktataj, do ne eblas preterlasi: {ids}",
|
||||||
|
"permission_already_exist": "Permesita '{permission}' jam ekzistas",
|
||||||
|
"domain_created": "Domajno kreita",
|
||||||
|
"migrate_tsig_wait_2": "2 minutoj …",
|
||||||
|
"log_user_create": "Aldonu uzanton '{}'",
|
||||||
|
"ip6tables_unavailable": "Vi ne povas ludi kun ip6tabloj ĉi tie. Vi estas en ujo aŭ via kerno ne subtenas ĝin",
|
||||||
|
"mail_unavailable": "Ĉi tiu retpoŝta adreso estas rezervita kaj aŭtomate estos atribuita al la unua uzanto",
|
||||||
|
"certmanager_domain_dns_ip_differs_from_public_ip": "La DNS 'A' rekordo por la domajno '{domain:s}' diferencas de ĉi tiu IP-servilo. Se vi lastatempe modifis vian A-registron, bonvolu atendi ĝin propagandi (iuj DNS-disvastigaj kontroliloj estas disponeblaj interrete). (Se vi scias, kion vi faras, uzu '--no-checks' por malŝalti tiujn ĉekojn.)",
|
||||||
|
"tools_upgrade_special_packages_completed": "Plenumis la ĝisdatigon de pakaĵoj de YunoHost.\nPremu [Enter] por retrovi la komandlinion",
|
||||||
|
"log_remove_on_failed_install": "Forigu '{}' post malsukcesa instalado",
|
||||||
|
"regenconf_file_manually_modified": "La agorddosiero '{conf}' estis modifita permane kaj ne estos ĝisdatigita",
|
||||||
|
"regenconf_would_be_updated": "La agordo estus aktualigita por la kategorio '{category}'",
|
||||||
|
"certmanager_cert_install_success_selfsigned": "Mem-subskribita atestilo nun instalita por la domajno '{domain:s}'",
|
||||||
|
"global_settings_unknown_setting_from_settings_file": "Nekonata ŝlosilo en agordoj: '{setting_key:s}', forĵetu ĝin kaj konservu ĝin en /etc/yunohost/settings-unknown.json",
|
||||||
|
"regenconf_file_backed_up": "Agordodosiero '{conf}' estis rezervita al '{backup}'",
|
||||||
|
"migration_0007_cannot_restart": "SSH ne rekomencas post provi nuligi la migradan numeron 6.",
|
||||||
|
"migration_description_0006_sync_admin_and_root_passwords": "Sinkronigu admin kaj radikajn pasvortojn",
|
||||||
|
"iptables_unavailable": "Vi ne povas ludi kun iptables ĉi tie. Vi estas en ujo aŭ via kerno ne subtenas ĝin",
|
||||||
|
"global_settings_cant_write_settings": "Ne eblis konservi agordojn, tial: {reason:s}",
|
||||||
|
"service_added": "La servo '{service:s}' aldonis",
|
||||||
|
"upnp_disabled": "UPnP malŝaltis",
|
||||||
|
"service_started": "Servo '{service:s}' komenciĝis",
|
||||||
|
"port_already_opened": "Haveno {port:d} estas jam malfermita por {ip_version:s} rilatoj",
|
||||||
|
"installation_failed": "Io okazis malbone kun la instalado",
|
||||||
|
"migrate_tsig_wait_3": "1 minuto …",
|
||||||
|
"certmanager_conflicting_nginx_file": "Ne povis prepari domajnon por ACME-defio: la agordo de NGINX {filepath:s} konfliktas kaj unue devas esti forigita",
|
||||||
|
"upgrading_packages": "Ĝisdatigi pakojn…",
|
||||||
|
"custom_app_url_required": "Vi devas provizi URL por altgradigi vian kutimon app {app:s}",
|
||||||
|
"service_reload_failed": "Ne povis reŝargi la servon '{service:s}'\n\nLastatempaj servaj protokoloj: {logs:s}",
|
||||||
|
"packages_upgrade_failed": "Ne povis ĝisdatigi ĉiujn pakojn",
|
||||||
|
"hook_json_return_error": "Ne povis legi revenon de hoko {path:s}. Eraro: {msg:s}. Kruda enhavo: {raw_content}",
|
||||||
|
"dyndns_cron_removed": "DynDNS cron-laboro forigita",
|
||||||
|
"dyndns_key_not_found": "DNS-ŝlosilo ne trovita por la domajno",
|
||||||
|
"tools_upgrade_regular_packages_failed": "Ne povis ĝisdatigi pakojn: {packages_list}",
|
||||||
|
"service_start_failed": "Ne povis komenci la servon '{service:s}'\n\nLastatempaj servaj protokoloj: {logs:s}",
|
||||||
|
"service_reloaded": "Servo '{service:s}' reŝargita",
|
||||||
|
"system_upgraded": "Sistemo ĝisdatigita",
|
||||||
|
"domain_deleted": "Domajno forigita",
|
||||||
|
"certmanager_acme_not_configured_for_domain": "Atestilo por la domajno '{domain:s}' ne ŝajnas esti ĝuste instalita. Bonvolu ekzekuti 'cert-instali' por ĉi tiu regado unue.",
|
||||||
|
"migration_description_0009_decouple_regenconf_from_services": "Malkonstruu la regen-konf-mekanismon de servoj",
|
||||||
|
"user_update_failed": "Ne povis ĝisdatigi uzanton {user}: {error}",
|
||||||
|
"migration_description_0008_ssh_conf_managed_by_yunohost_step2": "Lasu la SSH-agordon estu administrata de YunoHost (paŝo 2, manlibro)",
|
||||||
|
"restore_confirm_yunohost_installed": "Ĉu vi vere volas restarigi jam instalitan sistemon? [{answers:s}]",
|
||||||
|
"pattern_positive_number": "Devas esti pozitiva nombro",
|
||||||
|
"certmanager_error_no_A_record": "Neniu DNS 'A' rekordo trovita por '{domain:s}'. Vi bezonas atentigi vian domajnan nomon al via maŝino por povi instali atestilon Lasu-Ĉifri. (Se vi scias, kion vi faras, uzu '--no-checks' por malŝalti tiujn ĉekojn.)",
|
||||||
|
"update_apt_cache_failed": "Ne eblis ĝisdatigi la kaŝmemoron de APT (paka administranto de Debian). Jen rubujo de la sources.list-linioj, kiuj povus helpi identigi problemajn liniojn:\n{sourceslist}",
|
||||||
|
"migrations_no_migrations_to_run": "Neniuj migradoj por funkcii",
|
||||||
|
"executing_command": "Plenumanta komandon '{command:s}' …",
|
||||||
|
"certmanager_attempt_to_renew_nonLE_cert": "La atestilo por la domajno '{domain:s}' ne estas elsendita de Let's Encrypt. Ne eblas renovigi ĝin aŭtomate!",
|
||||||
|
"global_settings_setting_example_bool": "Ekzemplo bulea elekto",
|
||||||
|
"domain_dyndns_already_subscribed": "Vi jam abonis DynDNS-domajnon",
|
||||||
|
"log_letsencrypt_cert_renew": "Renovigu '{}' Let's Encrypt atestilon",
|
||||||
|
"migrate_tsig_start": "Detektita ŝlosila algoritmo nesufiĉa por TSIG-subskribo de la domajno '{domain}', komencanta migradon al la pli sekura HMAC-SHA-512",
|
||||||
|
"ldap_init_failed_to_create_admin": "LDAP-iniciato ne povis krei administran uzanton",
|
||||||
|
"backup_output_directory_required": "Vi devas provizi elirejan dosierujon por la sekurkopio",
|
||||||
|
"tools_upgrade_cant_unhold_critical_packages": "Ne povis malŝalti kritikajn pakojn…",
|
||||||
|
"log_link_to_log": "Plena ŝtipo de ĉi tiu operacio: '<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\"> {desc} </a>'",
|
||||||
|
"global_settings_cant_serialize_settings": "Ne eblis serialigi datumojn pri agordoj, motivo: {reason:s}",
|
||||||
|
"backup_running_hooks": "Kurado de apogaj hokoj …",
|
||||||
|
"certmanager_domain_unknown": "Nekonata domajno '{domain:s}'",
|
||||||
|
"unexpected_error": "Io neatendita iris malbone: {error}",
|
||||||
|
"password_listed": "Ĉi tiu pasvorto estas inter la plej uzataj pasvortoj en la mondo. Bonvolu elekti ion pli unikan.",
|
||||||
|
"migration_description_0007_ssh_conf_managed_by_yunohost_step1": "Lasu la SSH-agordon estu administrata de YunoHost (paŝo 1, aŭtomata)",
|
||||||
|
"migration_0009_not_needed": "Ĉi tiu migrado jam iel okazis ... (?) Saltado.",
|
||||||
|
"ssowat_conf_generated": "SSOwat-agordo generita",
|
||||||
|
"migrate_tsig_wait": "Atendante tri minutojn por ke la servilo DynDNS enkalkulu la novan ŝlosilon …",
|
||||||
|
"log_remove_on_failed_restore": "Forigu '{}' post malsukcesa restarigo de rezerva ar archiveivo",
|
||||||
|
"dpkg_is_broken": "Vi ne povas fari ĉi tion nun ĉar dpkg/APT (la administrantoj pri pakaĵaj sistemoj) ŝajnas esti rompita stato ... Vi povas provi solvi ĉi tiun problemon per konekto per SSH kaj funkcianta `sudo dpkg --configure -a`.",
|
||||||
|
"certmanager_cert_signing_failed": "Ne povis subskribi la novan atestilon",
|
||||||
|
"migration_description_0003_migrate_to_stretch": "Altgradigu la sistemon al Debian Stretch kaj YunoHost 3.0",
|
||||||
|
"log_tools_upgrade": "Ĝisdatigu sistemajn pakaĵojn",
|
||||||
|
"log_available_on_yunopaste": "Ĉi tiu protokolo nun haveblas per {url}",
|
||||||
|
"certmanager_http_check_timeout": "Ekdifinita kiam servilo provis kontakti sin per HTTP per publika IP-adreso (domajno '{domain:s}' kun IP '{ip:s}'). Vi eble spertas haŭtoproblemon, aŭ la fajroŝirmilo / enkursigilo antaŭ via servilo miskonfiguras.",
|
||||||
|
"pattern_port_or_range": "Devas esti valida haveno-nombro (t.e. 0-65535) aŭ gamo da havenoj (t.e. 100:200)",
|
||||||
|
"migrations_loading_migration": "Ŝarĝante migradon {id}…",
|
||||||
|
"pattern_mailbox_quota": "Devas esti grandeco kun la sufikso b/k/M/G/T aŭ 0 por ne havi kvoton",
|
||||||
|
"migration_0008_general_disclaimer": "Por plibonigi la sekurecon de via servilo, rekomendas lasi YunoHost administri la SSH-agordon. Via nuna SSH-aranĝo diferencas de la rekomendo. Se vi lasas YunoHost agordi ĝin, la maniero per kiu vi konektas al via servilo per SSH ŝanĝiĝos tiel:",
|
||||||
|
"user_deletion_failed": "Ne povis forigi uzanton {user}: {error}",
|
||||||
|
"backup_with_no_backup_script_for_app": "La app '{app:s}' ne havas sekretan skripton. Ignorante.",
|
||||||
|
"service_regen_conf_is_deprecated": "'yunohost service regen-conf' malakceptas! Bonvolu uzi anstataŭe 'yunohost tools regen-conf'.",
|
||||||
|
"global_settings_key_doesnt_exists": "La ŝlosilo '{settings_key:s}' ne ekzistas en la tutmondaj agordoj, vi povas vidi ĉiujn disponeblajn klavojn per uzado de 'yunohost settings list'",
|
||||||
|
"dyndns_no_domain_registered": "Neniu domajno registrita ĉe DynDNS",
|
||||||
|
"dyndns_could_not_check_available": "Ne povis kontroli ĉu {domain:s} haveblas sur {provider:s}.",
|
||||||
|
"global_settings_setting_example_enum": "Ekzemplo enum elekto",
|
||||||
|
"hook_exec_not_terminated": "Skripto ne finiĝis ĝuste: {path:s}",
|
||||||
|
"service_stopped": "Servo '{service:s}' ĉesis",
|
||||||
|
"restore_failed": "Ne povis restarigi sistemon",
|
||||||
|
"confirm_app_install_danger": "Danĝero! Ĉi tiu apliko estas konata ankoraŭ eksperimenta (se ne eksplicite ne funkcias)! Vi probable ne devas instali ĝin krom se vi scias kion vi faras. NENIU SUBTENO estos provizita se ĉi tiu app ne funkcias aŭ rompas vian sistemon ... Se vi pretas riski ĉiuokaze, tajpu '{answers:s}'",
|
||||||
|
"log_operation_unit_unclosed_properly": "Operaciumo ne estis fermita ĝuste",
|
||||||
|
"upgrade_complete": "Ĝisdatigo kompleta",
|
||||||
|
"upnp_enabled": "UPnP ŝaltis",
|
||||||
|
"mailbox_used_space_dovecot_down": "La retpoŝta servo de Dovecot devas funkcii, se vi volas akcepti uzitan poŝtan spacon",
|
||||||
|
"restore_system_part_failed": "Ne povis restarigi la sisteman parton '{part:s}'",
|
||||||
|
"service_stop_failed": "Ne povis maldaŭrigi la servon '{service:s}'\n\nLastatempaj servaj protokoloj: {logs:s}",
|
||||||
|
"unbackup_app": "App '{app:s}' ne konserviĝos",
|
||||||
|
"updating_apt_cache": "Akirante haveblajn ĝisdatigojn por sistemaj pakoj…",
|
||||||
|
"tools_upgrade_at_least_one": "Bonvolu specifi '--apps' aŭ '--system'",
|
||||||
|
"service_already_stopped": "La servo '{service:s}' jam ĉesis",
|
||||||
|
"migration_0003_modified_files": "Bonvolu noti, ke la jenaj dosieroj estis trovitaj mane kaj modifitaj kaj povus esti anstataŭigitaj sekve de la ĝisdatigo: {manually_modified_files}",
|
||||||
|
"tools_upgrade_cant_both": "Ne eblas ĝisdatigi ambaŭ sistemon kaj programojn samtempe",
|
||||||
|
"restore_extracting": "Eltirante bezonatajn dosierojn el la ar theivo…",
|
||||||
|
"upnp_port_open_failed": "Ne povis malfermi havenon per UPnP",
|
||||||
|
"log_app_upgrade": "Ĝisdatigu la aplikon '{}'",
|
||||||
|
"log_help_to_get_failed_log": "La operacio '{desc}' ne povis finiĝi. Bonvolu dividi la plenan ŝtipon de ĉi tiu operacio per la komando 'yunohost log display {name} --share' por akiri helpon",
|
||||||
|
"migration_description_0002_migrate_to_tsig_sha256": "Plibonigu sekurecon de DynDNS TSIG-ĝisdatigoj per SHA-512 anstataŭ MD5",
|
||||||
|
"port_already_closed": "Haveno {port:d} estas jam fermita por {ip_version:s} rilatoj",
|
||||||
|
"hook_name_unknown": "Nekonata hoko-nomo '{name:s}'",
|
||||||
|
"migration_0003_system_not_fully_up_to_date": "Via sistemo ne estas plene ĝisdata. Bonvolu plenumi regulan ĝisdatigon antaŭ ol ruli la migradon al Stretch.",
|
||||||
|
"dyndns_could_not_check_provide": "Ne povis kontroli ĉu {provider:s} povas provizi {domain:s}.",
|
||||||
|
"dyndns_cron_remove_failed": "Ne povis forigi la cron-laboron DynDNS ĉar: {error}",
|
||||||
|
"restore_nothings_done": "Nenio estis restarigita",
|
||||||
|
"log_tools_postinstall": "Afiŝu vian servilon YunoHost",
|
||||||
|
"dyndns_unavailable": "La domajno '{domain:s}' ne haveblas.",
|
||||||
|
"experimental_feature": "Averto: Ĉi tiu funkcio estas eksperimenta kaj ne konsiderata stabila, vi ne uzu ĝin krom se vi scias kion vi faras.",
|
||||||
|
"root_password_replaced_by_admin_password": "Via radika pasvorto estis anstataŭigita per via administra pasvorto.",
|
||||||
|
"migration_description_0005_postgresql_9p4_to_9p6": "Migru datumbazojn de PostgreSQL 9.4 al 9.6",
|
||||||
|
"migration_0008_root": "• Vi ne povos konekti kiel radiko per SSH. Anstataŭe vi uzu la administran uzanton;",
|
||||||
|
"package_unknown": "Nekonata pako '{pkgname}'",
|
||||||
|
"domain_unknown": "Nekonata domajno",
|
||||||
|
"global_settings_setting_security_password_user_strength": "Uzanto pasvorta forto",
|
||||||
|
"restore_may_be_not_enough_disk_space": "Via sistemo ŝajnas ne havi sufiĉe da spaco (free:{free_space:d} B, necesa spaco: {needed_space:d} B, sekureca marĝeno: {margin:d} B)",
|
||||||
|
"log_corrupted_md_file": "La YAD-metadata dosiero asociita kun protokoloj estas damaĝita: '{md_file}\nEraro: {error} '",
|
||||||
|
"downloading": "Elŝutante …",
|
||||||
|
"user_deleted": "Uzanto forigita",
|
||||||
|
"service_enable_failed": "Ne povis fari la servon '{service:s}' aŭtomate komenci ĉe la ekkuro.\n\nLastatempaj servaj protokoloj: {logs:s}",
|
||||||
|
"tools_upgrade_special_packages": "Nun ĝisdatigi 'specialajn' (rilatajn al yunohost)…",
|
||||||
|
"domains_available": "Haveblaj domajnoj:",
|
||||||
|
"dyndns_registered": "Registrita domajno DynDNS",
|
||||||
|
"service_description_fail2ban": "Protektas kontraŭ bruta forto kaj aliaj specoj de atakoj de la interreto",
|
||||||
|
"file_does_not_exist": "La dosiero {path:s} ne ekzistas.",
|
||||||
|
"yunohost_not_installed": "YunoHost ne estas ĝuste instalita. Bonvolu prilabori 'yunohost tools postinstall'",
|
||||||
|
"migration_0005_postgresql_96_not_installed": "PostgreSQL 9.4 estas instalita, sed ne postgresql 9.6‽ Io stranga eble okazis en via sistemo: (…",
|
||||||
|
"restore_removing_tmp_dir_failed": "Ne povis forigi malnovan provizoran dosierujon",
|
||||||
|
"certmanager_cannot_read_cert": "Io malbona okazis, kiam mi provis malfermi aktualan atestilon por domajno {domain:s} (dosiero: {file:s}), kialo: {reason:s}",
|
||||||
|
"service_removed": "Servo '{service:s}' forigita",
|
||||||
|
"certmanager_hit_rate_limit": "Tro multaj atestiloj jam eldonitaj por ĉi tiu ĝusta aro de domajnoj {domain:s} antaŭ nelonge. Bonvolu reprovi poste. Vidu https://letsencrypt.org/docs/rate-limits/ por pliaj detaloj",
|
||||||
|
"migration_0005_not_enough_space": "Disponigu sufiĉan spacon en {path} por ruli la migradon.",
|
||||||
|
"pattern_firstname": "Devas esti valida antaŭnomo",
|
||||||
|
"migration_description_0010_migrate_to_apps_json": "Forigu malvalorigitajn katalogajn programojn kaj uzu anstataŭe la novan unuigitan liston de \"apps.json\" (malaktuale anstataŭita per migrado 13)",
|
||||||
|
"domain_cert_gen_failed": "Ne povis generi atestilon",
|
||||||
|
"regenconf_file_kept_back": "La agorda dosiero '{conf}' estas atendita forigi per regen-conf (kategorio {category}), sed ĝi estis konservita.",
|
||||||
|
"migrate_tsig_wait_4": "30 sekundoj …",
|
||||||
|
"backup_with_no_restore_script_for_app": "La apliko \"{app:s}\" ne havas restarigan skripton, vi ne povos aŭtomate restarigi la sekurkopion de ĉi tiu apliko.",
|
||||||
|
"log_letsencrypt_cert_install": "Instalu atestilon Let's Encrypt sur '{}' regado",
|
||||||
|
"log_dyndns_update": "Ĝisdatigu la IP asociita kun via subdominio YunoHost '{}'",
|
||||||
|
"firewall_reload_failed": "Ne eblis reŝargi la firewall",
|
||||||
|
"confirm_app_install_warning": "Averto: Ĉi tiu aplikaĵo povas funkcii, sed ne bone integras en YunoHost. Iuj funkcioj kiel ekzemple aliĝilo kaj sekurkopio / restarigo eble ne haveblos. Instali ĉiuokaze? [{answers:s}] ",
|
||||||
|
"log_user_delete": "Forigi uzanton '{}'",
|
||||||
|
"dyndns_ip_updated": "Ĝisdatigis vian IP sur DynDNS",
|
||||||
|
"regenconf_up_to_date": "La agordo jam estas ĝisdatigita por kategorio '{category}'",
|
||||||
|
"migration_0003_patching_sources_list": "Patching the sources.lists …",
|
||||||
|
"global_settings_setting_security_ssh_compatibility": "Kongruo vs sekureca kompromiso por la SSH-servilo. Afektas la ĉifradojn (kaj aliajn aspektojn pri sekureco)",
|
||||||
|
"migrations_need_to_accept_disclaimer": "Por funkciigi la migradon {id}, via devas akcepti la sekvan malakcepton:\n---\n{disclaimer}\n---\nSe vi akceptas funkcii la migradon, bonvolu rekonduki la komandon kun la opcio '--accept-disclaimer'.",
|
||||||
|
"regenconf_file_remove_failed": "Ne povis forigi la agordodosieron '{conf}'",
|
||||||
|
"not_enough_disk_space": "Ne sufiĉe libera spaco sur '{path:s}'",
|
||||||
|
"migration_0006_disclaimer": "YunoHost nun atendas, ke la pasvortoj de admin kaj radiko estos sinkronigitaj. Ĉi tiu migrado anstataŭigas vian radikan pasvorton kun la administran pasvorton.",
|
||||||
|
"dyndns_ip_update_failed": "Ne povis ĝisdatigi IP-adreson al DynDNS",
|
||||||
|
"migration_description_0004_php5_to_php7_pools": "Rekonfigu la PHP-naĝejojn por uzi PHP 7 anstataŭ 5",
|
||||||
|
"ssowat_conf_updated": "SSOwat-agordo ĝisdatigita",
|
||||||
|
"log_link_to_failed_log": "Ne povis plenumi la operacion '{desc}'. Bonvolu provizi la plenan protokolon de ĉi tiu operacio per <a href=\"#/tools/logs/{name}\"> alklakante ĉi tie </a> por akiri helpon",
|
||||||
|
"user_home_creation_failed": "Ne povis krei dosierujon \"home\" por uzanto",
|
||||||
|
"pattern_backup_archive_name": "Devas esti valida dosiernomo kun maksimume 30 signoj, alfanombraj kaj -_. signoj nur",
|
||||||
|
"restore_cleaning_failed": "Ne eblis purigi la adresaron de provizora restarigo",
|
||||||
|
"dyndns_registration_failed": "Ne povis registri DynDNS-domajnon: {error:s}",
|
||||||
|
"migration_0003_not_jessie": "La nuna Debian-distribuo ne estas Jessie!",
|
||||||
|
"user_unknown": "Nekonata uzanto: {user:s}",
|
||||||
|
"migrations_to_be_ran_manually": "Migrado {id} devas funkcii permane. Bonvolu iri al Iloj → Migradoj en la retpaĝa paĝo, aŭ kuri `yunohost tools migrations migrate`.",
|
||||||
|
"migration_0008_warning": "Se vi komprenas tiujn avertojn kaj volas ke YunoHost preterlasu vian nunan agordon, faru la migradon. Alie, vi ankaŭ povas salti la migradon, kvankam ĝi ne rekomendas.",
|
||||||
|
"certmanager_cert_renew_success": "Ni Ĉifru atestilon renovigitan por la domajno '{domain:s}'",
|
||||||
|
"global_settings_reset_success": "Antaŭaj agordoj nun estas rezervitaj al {path:s}",
|
||||||
|
"pattern_domain": "Devas esti valida domajna nomo (t.e. mia-domino.org)",
|
||||||
|
"dyndns_key_generating": "Generi DNS-ŝlosilon ... Eble daŭros iom da tempo.",
|
||||||
|
"restore_running_app_script": "Restarigi la programon '{app:s}'…",
|
||||||
|
"migrations_skip_migration": "Salti migradon {id}…",
|
||||||
|
"regenconf_file_removed": "Agordodosiero '{conf}' forigita",
|
||||||
|
"log_tools_shutdown": "Enŝaltu vian servilon",
|
||||||
|
"password_too_simple_3": "La pasvorto bezonas almenaŭ 8 signojn kaj enhavas ciferon, majusklon, pli malaltan kaj specialajn signojn",
|
||||||
|
"migration_0003_general_warning": "Bonvolu noti, ke ĉi tiu migrado estas delikata operacio. La teamo de YunoHost faris sian plej bonan revizii kaj testi ĝin, sed la migrado eble ankoraŭ rompos partojn de la sistemo aŭ ĝiaj programoj.\n\nTial oni rekomendas al:\n - Elfari kopion de iuj kritikaj datumoj aŭ app. Pliaj informoj pri https://yunohost.org/backup;\n - Paciencu post lanĉo de la migrado: Depende de via interreta konekto kaj aparataro, eble daŭros kelkaj horoj ĝis ĉio ĝisdatigi.\n\nAldone, la haveno por SMTP, uzata de eksteraj retpoŝtaj klientoj (kiel Thunderbird aŭ K9-Mail) estis ŝanĝita de 465 (SSL / TLS) al 587 (STARTTLS). La malnova haveno (465) aŭtomate fermiĝos, kaj la nova haveno (587) malfermiĝos en la fajrejo. Vi kaj viaj uzantoj * devos adapti la agordon de viaj retpoŝtaj klientoj laŭe.",
|
||||||
|
"global_settings_setting_example_int": "Ekzemple int elekto",
|
||||||
|
"backup_output_symlink_dir_broken": "Via arkiva dosierujo '{path:s}' estas rompita ligilo. Eble vi forgesis restarigi aŭ munti aŭ enŝovi la stokadon, al kiu ĝi notas.",
|
||||||
|
"good_practices_about_admin_password": "Vi nun estas por difini novan administran pasvorton. La pasvorto devas esti almenaŭ 8 signoj - kvankam estas bone praktiki uzi pli longan pasvorton (t.e. pasfrazon) kaj / aŭ uzi variaĵon de signoj (majuskloj, minuskloj, ciferoj kaj specialaj signoj).",
|
||||||
|
"certmanager_attempt_to_renew_valid_cert": "La atestilo por la domajno '{domain:s}' ne finiĝos! (Vi eble uzos --force se vi scias kion vi faras)",
|
||||||
|
"restore_running_hooks": "Kurantaj restarigaj hokoj…",
|
||||||
|
"regenconf_pending_applying": "Aplikante pritraktata agordo por kategorio '{category}'…",
|
||||||
|
"service_description_dovecot": "Permesas al retpoŝtaj klientoj aliri / serĉi retpoŝton (per IMAP kaj POP3)",
|
||||||
|
"domain_dns_conf_is_just_a_recommendation": "Ĉi tiu komando montras al vi la *rekomenditan* agordon. Ĝi efektive ne agordas la DNS-agordon por vi. Via respondeco agordi vian DNS-zonon en via registristo laŭ ĉi tiu rekomendo.",
|
||||||
|
"backup_php5_to_php7_migration_may_fail": "Ne povis konverti vian ar archiveivon por subteni PHP 7, vi eble ne povas restarigi viajn PHP-programojn (kialo: {error:s})",
|
||||||
|
"log_backup_restore_system": "Restarigi sistemon de rezerva arkivo",
|
||||||
|
"log_app_change_url": "Ŝanĝu la URL de la apliko '{}'",
|
||||||
|
"service_already_started": "La servo '{service:s}' jam funkcias",
|
||||||
|
"global_settings_setting_security_password_admin_strength": "Admin pasvorta forto",
|
||||||
|
"service_reload_or_restart_failed": "Ne povis reŝargi aŭ rekomenci la servon '{service:s}'\n\nLastatempaj servaj protokoloj: {logs:s}",
|
||||||
|
"migrations_list_conflict_pending_done": "Vi ne povas uzi ambaŭ '--previous' kaj '--done' samtempe.",
|
||||||
|
"server_shutdown_confirm": "La servilo haltos tuj, ĉu vi certas? [{answers:s}]",
|
||||||
|
"log_backup_restore_app": "Restarigu '{}' de rezerva ar archiveivo",
|
||||||
|
"log_does_exists": "Ne estas operacio-registro kun la nomo '{log}', uzu 'yunohost loglist' por vidi ĉiujn disponeblajn operaciojn",
|
||||||
|
"service_add_failed": "Ne povis aldoni la servon '{service:s}'",
|
||||||
|
"pattern_password_app": "Bedaŭrinde, pasvortoj ne povas enhavi jenajn signojn: {forbidden_chars}",
|
||||||
|
"this_action_broke_dpkg": "Ĉi tiu ago rompis dpkg / APT (la administrantoj pri la paka sistemo) ... Vi povas provi solvi ĉi tiun problemon per konekto per SSH kaj funkcianta `sudo dpkg --configure -a`.",
|
||||||
|
"log_regen_conf": "Regeneri sistemajn agordojn '{}'",
|
||||||
|
"restore_hook_unavailable": "La restariga skripto por '{part:s}' ne haveblas en via sistemo kaj ankaŭ ne en la ar theivo",
|
||||||
|
"log_dyndns_subscribe": "Aboni al YunoHost-subdominio '{}'",
|
||||||
|
"password_too_simple_4": "La pasvorto bezonas almenaŭ 12 signojn kaj enhavas ciferon, majuskle, pli malaltan kaj specialajn signojn",
|
||||||
|
"migration_0003_main_upgrade": "Komencanta ĉefa ĝisdatigo …",
|
||||||
|
"regenconf_file_updated": "Agordodosiero '{conf}' ĝisdatigita",
|
||||||
|
"log_help_to_get_log": "Por vidi la protokolon de la operacio '{desc}', uzu la komandon 'yunohost log display {name}'",
|
||||||
|
"global_settings_setting_security_nginx_compatibility": "Kongruo vs sekureca kompromiso por la TTT-servilo NGINX. Afektas la ĉifradojn (kaj aliajn aspektojn pri sekureco)",
|
||||||
|
"no_internet_connection": "La servilo ne estas konektita al la interreto",
|
||||||
|
"migration_0008_dsa": "• La DSA-ŝlosilo estos malŝaltita. Tial vi eble bezonos nuligi spuran averton de via SSH-kliento kaj revizii la fingrospuron de via servilo;",
|
||||||
|
"migration_0003_restoring_origin_nginx_conf": "Fileia dosiero /etc/nginx/nginx.conf estis iel redaktita. La migrado reaperos unue al sia originala stato ... La antaŭa dosiero estos havebla kiel {backup_dest}.",
|
||||||
|
"migrate_tsig_end": "Migrado al HMAC-SHA-512 finiĝis",
|
||||||
|
"restore_complete": "Restarigita",
|
||||||
|
"certmanager_couldnt_fetch_intermediate_cert": "Ekvilibrigita kiam vi provis ricevi interajn atestilojn de Let's Encrypt. Atestita instalado / renovigo nuligita - bonvolu reprovi poste.",
|
||||||
|
"hook_exec_failed": "Ne povis funkcii skripto: {path:s}",
|
||||||
|
"global_settings_cant_open_settings": "Ne eblis malfermi agordojn, tial: {reason:s}",
|
||||||
|
"user_created": "Uzanto kreita",
|
||||||
|
"service_description_avahi-daemon": "Permesas al vi atingi vian servilon uzante 'yunohost.local' en via loka reto",
|
||||||
|
"certmanager_attempt_to_replace_valid_cert": "Vi provas anstataŭigi bonan kaj validan atestilon por domajno {domain:s}! (Uzu --forte pretervidi)",
|
||||||
|
"regenconf_updated": "Agordo ĝisdatigita por '{category}'",
|
||||||
|
"update_apt_cache_warning": "Io iris malbone dum la ĝisdatigo de la kaŝmemoro de APT (paka administranto de Debian). Jen rubujo de la sources.list-linioj, kiuj povus helpi identigi problemajn liniojn:\n{sourceslist}",
|
||||||
|
"regenconf_dry_pending_applying": "Kontrolado de pritraktata agordo, kiu estus aplikita por kategorio '{category}'…",
|
||||||
|
"regenconf_file_copy_failed": "Ne povis kopii la novan agordodosieron '{new}' al '{conf}'",
|
||||||
|
"global_settings_setting_example_string": "Ekzemple korda elekto",
|
||||||
|
"restore_already_installed_app": "App kun la ID '{app:s}' estas jam instalita",
|
||||||
|
"mail_domain_unknown": "Nevalida retadreso por domajno '{domain:s}'. Bonvolu uzi domajnon administritan de ĉi tiu servilo.",
|
||||||
|
"migrations_cant_reach_migration_file": "Ne povis aliri migrajn dosierojn ĉe la vojo '% s'",
|
||||||
|
"pattern_email": "Devas esti valida retpoŝta adreso (t.e. iu@ekzemple.com)",
|
||||||
|
"mail_alias_remove_failed": "Ne povis forigi retpoŝton alias '{mail:s}'",
|
||||||
|
"regenconf_file_manually_removed": "La dosiero de agordo '{conf}' estis forigita permane, kaj ne estos kreita",
|
||||||
|
"domain_exists": "La domajno jam ekzistas",
|
||||||
|
"migration_description_0001_change_cert_group_to_sslcert": "Ŝanĝu grupajn permesojn de 'metronomo' al 'ssl-cert'",
|
||||||
|
"ldap_initialized": "LDAP inicializis",
|
||||||
|
"migrate_tsig_not_needed": "Vi ne ŝajnas uzi DynDNS-domajnon, do neniu migrado necesas.",
|
||||||
|
"certmanager_domain_cert_not_selfsigned": "La atestilo por domajno {domain:s} ne estas mem-subskribita. Ĉu vi certas, ke vi volas anstataŭigi ĝin? (Uzu '--force' por fari tion.)",
|
||||||
|
"certmanager_unable_to_parse_self_CA_name": "Ne povis trapasi nomon de mem-subskribinta aŭtoritato (dosiero: {file:s})",
|
||||||
|
"log_selfsigned_cert_install": "Instalu mem-subskribitan atestilon sur '{}' domajno",
|
||||||
|
"log_tools_reboot": "Reklamu vian servilon",
|
||||||
|
"certmanager_cert_install_success": "Ni Ĉifru atestilon nun instalitan por la domajno '{domain:s}'",
|
||||||
|
"global_settings_bad_choice_for_enum": "Malbona elekto por agordo {setting:s}, ricevita '{choice:s}', sed disponeblaj elektoj estas: {available_choices:s}",
|
||||||
|
"server_shutdown": "La servilo haltos",
|
||||||
|
"log_tools_migrations_migrate_forward": "Migri antaŭen",
|
||||||
|
"migration_0008_no_warning": "Supersalti vian SSH-agordon estu sekura, kvankam ĉi tio ne povas esti promesita! Ekfunkciu la migradon por superregi ĝin. Alie, vi ankaŭ povas salti la migradon, kvankam ĝi ne rekomendas.",
|
||||||
|
"regenconf_now_managed_by_yunohost": "La agorda dosiero '{conf}' nun estas administrata de YunoHost (kategorio {category}).",
|
||||||
|
"server_reboot_confirm": "Ĉu la servilo rekomencos tuj, ĉu vi certas? [{answers:s}]",
|
||||||
|
"log_app_install": "Instalu la aplikon '{}'",
|
||||||
|
"service_description_dnsmasq": "Traktas rezolucion de domajna nomo (DNS)",
|
||||||
|
"global_settings_unknown_type": "Neatendita situacio, la agordo {setting:s} ŝajnas havi la tipon {unknown_type:s} sed ĝi ne estas tipo subtenata de la sistemo.",
|
||||||
|
"migration_0003_problematic_apps_warning": "Bonvolu noti, ke la sekvaj eventuale problemaj instalitaj programoj estis detektitaj. Ŝajnas, ke tiuj ne estis instalitaj el app_katalogo aŭ ne estas markitaj kiel \"funkciantaj\". Tial ne eblas garantii, ke ili ankoraŭ funkcios post la ĝisdatigo: {problematic_apps}",
|
||||||
|
"domain_hostname_failed": "Ne povis agordi novan gastigilon. Ĉi tio eble kaŭzos problemon poste (eble bone).",
|
||||||
|
"server_reboot": "La servilo rekomenciĝos",
|
||||||
|
"regenconf_failed": "Ne povis regeneri la agordon por kategorio(j): {categories}",
|
||||||
|
"domain_uninstall_app_first": "Unu aŭ pluraj programoj estas instalitaj en ĉi tiu domajno. Bonvolu malinstali ilin antaŭ ol daŭrigi la domajnan forigon",
|
||||||
|
"service_unknown": "Nekonata servo '{service:s}'",
|
||||||
|
"migration_0003_start": "Komencante migradon al Stretch. La protokoloj haveblos en {logfile}.",
|
||||||
|
"domain_deletion_failed": "Ne eblas forigi domajnon {domain}: {error}",
|
||||||
|
"log_user_update": "Ĝisdatigu uzantinformojn de '{}'",
|
||||||
|
"user_creation_failed": "Ne povis krei uzanton {user}: {error}",
|
||||||
|
"migrations_migration_has_failed": "Migrado {id} ne kompletigis, abolis. Eraro: {exception}",
|
||||||
|
"done": "Farita",
|
||||||
|
"log_domain_remove": "Forigi domon '{}' de agordo de sistemo",
|
||||||
|
"hook_list_by_invalid": "Ĉi tiu posedaĵo ne povas esti uzata por listigi hokojn",
|
||||||
|
"confirm_app_install_thirdparty": "Danĝero! Ĉi tiu apliko ne estas parto de la aplika katalogo de Yunohost. Instali triajn aplikojn povas kompromiti la integrecon kaj sekurecon de via sistemo. Vi probable ne devas instali ĝin krom se vi scias kion vi faras. NENIU SUBTENO estos provizita se ĉi tiu app ne funkcias aŭ rompas vian sistemon ... Se vi pretas riski ĉiuokaze, tajpu '{answers:s}'",
|
||||||
|
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Permesu uzon de (malaktuala) DSA-hostkey por la agordo de daemon SSH",
|
||||||
|
"dyndns_domain_not_provided": "Provizanto DynDNS {provider:s} ne povas provizi domajnon {domain:s}.",
|
||||||
|
"backup_unable_to_organize_files": "Ne povis uzi la rapidan metodon por organizi dosierojn en la ar archiveivo",
|
||||||
|
"password_too_simple_2": "La pasvorto bezonas almenaŭ 8 signojn kaj enhavas ciferon, majusklojn kaj minusklojn",
|
||||||
|
"executing_script": "Plenumanta skripto '{script:s}' …",
|
||||||
|
"service_cmd_exec_failed": "Ne povis plenumi la komandon '{command:s}'",
|
||||||
|
"migration_0007_cancelled": "Ne povis plibonigi la manieron kiel via SSH-agordo estas administrita.",
|
||||||
|
"migrate_tsig_failed": "Ne povis migri la DynDNS-domajnon '{domain}' al HMAC-SHA-512, ruliĝante. Eraro: {error_code}, {error}",
|
||||||
|
"pattern_lastname": "Devas esti valida familinomo",
|
||||||
|
"service_enabled": "La servo '{service:s}' nun aŭtomate komenciĝos dum sistemaj botoj.",
|
||||||
|
"certmanager_no_cert_file": "Ne povis legi la atestan dosieron por la domajno {domain:s} (dosiero: {file:s})",
|
||||||
|
"migration_0008_port": "• Vi devos konekti uzante la havenon 22 anstataŭ via nuna kutimo SSH-haveno. Sentu vin libera reconfiguri ĝin;",
|
||||||
|
"domain_creation_failed": "Ne eblas krei domajnon {domain}: {error}",
|
||||||
|
"certmanager_domain_http_not_working": "Ŝajnas ke la domajno {domain:s} ne atingeblas per HTTP. Kontrolu, ke via DNS kaj NGINX-agordo ĝustas",
|
||||||
|
"domain_cannot_remove_main": "Vi ne povas forigi '{domain:s}' ĉar ĝi estas la ĉefa domajno, vi bezonas unue agordi alian domajnon kiel la ĉefan domajnon per uzado de 'yunohost domain main-domain -n <another-domain>', jen la listo de kandidataj domajnoj. : {other_domains:s}",
|
||||||
|
"service_reloaded_or_restarted": "La servo '{service:s}' estis reŝarĝita aŭ rekomencita",
|
||||||
|
"log_domain_add": "Aldonu '{}' domajnon en sisteman agordon",
|
||||||
|
"global_settings_bad_type_for_setting": "Malbona tipo por agordo {setting:s}, ricevita {received_type:s}, atendata {expected_type:s}",
|
||||||
|
"unlimit": "Neniu kvoto",
|
||||||
|
"dyndns_cron_installed": "Kreita laboro DynDNS cron",
|
||||||
|
"system_username_exists": "Uzantnomo jam ekzistas en la listo de uzantoj de sistemo",
|
||||||
|
"firewall_reloaded": "Fajroŝirmilo reŝarĝis",
|
||||||
|
"service_restarted": "Servo '{service:s}' rekomencis",
|
||||||
|
"pattern_username": "Devas esti minuskulaj literoj kaj minuskloj nur",
|
||||||
|
"extracting": "Eltirante…",
|
||||||
|
"restore_app_failed": "Ne povis restarigi la programon '{app:s}'",
|
||||||
|
"yunohost_configured": "YunoHost nun estas agordita",
|
||||||
|
"certmanager_self_ca_conf_file_not_found": "Ne povis trovi agorddosieron por mem-subskriba aŭtoritato (dosiero: {file:s})",
|
||||||
|
"log_app_remove": "Forigu la aplikon '{}'",
|
||||||
|
"service_restart_failed": "Ne povis rekomenci la servon '{service:s}'\n\nLastatempaj servaj protokoloj: {logs:s}",
|
||||||
|
"firewall_rules_cmd_failed": "Iuj komandoj pri fajroŝirmilo malsukcesis. Pliaj informoj en ensaluto.",
|
||||||
|
"certmanager_certificate_fetching_or_enabling_failed": "Provante uzi la novan atestilon por {domain:s} ne funkciis …",
|
||||||
|
"app_full_domain_unavailable": "Bedaŭrinde, ĉi tiu app devas esti instalita sur propra domajno, sed aliaj programoj jam estas instalitaj sur la domajno '{domain}'. Vi povus uzi subdominon dediĉitan al ĉi tiu app anstataŭe.",
|
||||||
|
"migration_0011_slapd_config_will_be_overwritten": "Ŝajnas ke vi permane redaktis la slapd-agordon. Por ĉi tiu kritika migrado, YunoHost bezonas devigi la ĝisdatigon de la slapd-agordo. La originalaj dosieroj estos rezervitaj en {conf_backup_folder}.",
|
||||||
|
"group_cannot_edit_all_users": "La grupo 'all_users' ne povas esti redaktita permane. Ĝi estas speciala grupo celita enhavi ĉiujn uzantojn registritajn en YunoHost",
|
||||||
|
"group_cannot_edit_visitors": "La grupo 'vizitantoj' ne povas esti redaktita permane. Ĝi estas speciala grupo reprezentanta anonimajn vizitantojn",
|
||||||
|
"group_cannot_edit_primary_group": "La grupo '{group}' ne povas esti redaktita permane. Ĝi estas la primara grupo celita enhavi nur unu specifan uzanton.",
|
||||||
|
"log_permission_url": "Ĝisdatigu url-rilataj al permeso '{}'",
|
||||||
|
"permission_already_up_to_date": "La permeso ne estis ĝisdatigita ĉar la petoj pri aldono/forigo jam kongruas kun la aktuala stato.",
|
||||||
|
"permission_currently_allowed_for_all_users": "Ĉi tiu permeso estas nuntempe donita al ĉiuj uzantoj aldone al aliaj grupoj. Vi probable volas aŭ forigi la permeson \"all_users\" aŭ forigi la aliajn grupojn, kiujn ĝi nuntempe donas.",
|
||||||
|
"app_install_failed": "Ne povis instali {app} : {error}",
|
||||||
|
"app_install_script_failed": "Eraro okazis en la skripto de instalado de la app",
|
||||||
|
"app_remove_after_failed_install": "Forigado de la app post la instala fiasko …",
|
||||||
|
"diagnosis_basesystem_host": "Servilo funkcias Debian {debian_version}.",
|
||||||
|
"apps_catalog_init_success": "Aplikoj katalogsistemo inicializita !",
|
||||||
|
"apps_catalog_updating": "Ĝisdatigante katalogo de aplikoj ...",
|
||||||
|
"apps_catalog_failed_to_download": "Ne eblas elŝuti la katalogon de {apps_catalog}: {error}",
|
||||||
|
"apps_catalog_obsolete_cache": "La kaŝmemoro de la katalogo de programoj estas malplena aŭ malaktuala.",
|
||||||
|
"apps_catalog_update_success": "La aplika katalogo estis ĝisdatigita!",
|
||||||
|
"diagnosis_basesystem_kernel": "Servilo funkcias Linuksan kernon {kernel_version}",
|
||||||
|
"diagnosis_basesystem_ynh_single_version": "{package} versio: {version} ({repo})",
|
||||||
|
"diagnosis_basesystem_ynh_main_version": "Servilo funkcias YunoHost {main_version} ({repo})",
|
||||||
|
"diagnosis_basesystem_ynh_inconsistent_versions": "Vi prizorgas malkonsekvencajn versiojn de la YunoHost-pakoj... plej probable pro malsukcesa aŭ parta ĝisdatigo.",
|
||||||
|
"diagnosis_display_tip_web": "Vi povas iri al la sekcio Diagnozo (en la hejmekrano) por vidi la trovitajn problemojn.",
|
||||||
|
"diagnosis_cache_still_valid": "(Kaŝmemoro ankoraŭ validas por {category} diagnozo. Ankoraŭ ne re-diagnoza!)",
|
||||||
|
"diagnosis_cant_run_because_of_dep": "Ne eblas fari diagnozon por {category} dum estas gravaj problemoj rilataj al {dep}.",
|
||||||
|
"diagnosis_display_tip_cli": "Vi povas aranĝi 'yunohost diagnosis show --issues' por aperigi la trovitajn problemojn.",
|
||||||
|
"diagnosis_failed_for_category": "Diagnozo malsukcesis por kategorio '{category}': {error}",
|
||||||
|
"app_upgrade_script_failed": "Eraro okazis en la skripto pri ĝisdatiga programo",
|
||||||
|
"diagnosis_diskusage_verylow": "Stokado {mountpoint} (sur aparato {device)) restas nur {free} ({free_percent}%) spaco. Vi vere konsideru purigi iom da spaco.",
|
||||||
|
"diagnosis_ram_verylow": "La sistemo nur restas {available} ({available_percent}%) RAM! (el {total})",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked": "Eliranta haveno 25 ŝajnas esti blokita. Vi devas provi malŝlosi ĝin en via agorda panelo de provizanto (aŭ gastiganto). Dume la servilo ne povos sendi retpoŝtojn al aliaj serviloj.",
|
||||||
|
"diagnosis_http_bad_status_code": "Ne povis atingi vian servilon kiel atendite, ĝi redonis malbonan statuskodon. Povas esti, ke alia maŝino respondis anstataŭ via servilo. Vi devus kontroli, ke vi ĝuste redonas la havenon 80, ke via nginx-agordo ĝisdatigas kaj ke reverso-prokuro ne interbatalas.",
|
||||||
|
"main_domain_changed": "La ĉefa domajno estis ŝanĝita",
|
||||||
|
"yunohost_postinstall_end_tip": "La post-instalado finiĝis! Por fini vian agordon, bonvolu konsideri:\n - aldonado de unua uzanto tra la sekcio 'Uzantoj' de la retadreso (aŭ 'yunohost user create <username>' en komandlinio);\n - diagnozi problemojn atendantajn solvi por ke via servilo funkciu kiel eble plej glate tra la sekcio 'Diagnosis' de la retadministrado (aŭ 'yunohost diagnosis run' en komandlinio);\n - legante la partojn 'Finigi vian agordon' kaj 'Ekkoni Yunohost' en la administra dokumentado: https://yunohost.org/admindoc.",
|
||||||
|
"migration_description_0014_remove_app_status_json": "Forigi heredajn dosierojn",
|
||||||
|
"diagnosis_ip_connected_ipv4": "La servilo estas konektita al la interreto per IPv4 !",
|
||||||
|
"diagnosis_ip_no_ipv4": "La servilo ne havas funkciantan IPv4.",
|
||||||
|
"diagnosis_ip_connected_ipv6": "La servilo estas konektita al la interreto per IPv6 !",
|
||||||
|
"diagnosis_ip_no_ipv6": "La servilo ne havas funkciantan IPv6.",
|
||||||
|
"diagnosis_ip_not_connected_at_all": "La servilo tute ne ŝajnas esti konektita al la Interreto !?",
|
||||||
|
"diagnosis_ip_dnsresolution_working": "Rezolucio pri domajna nomo funkcias !",
|
||||||
|
"diagnosis_ip_weird_resolvconf": "DNS-rezolucio ŝajnas funkcii, sed atentu, ke vi ŝajnas uzi kutimon /etc/resolv.conf.",
|
||||||
|
"diagnosis_ip_weird_resolvconf_details": "Anstataŭe, ĉi tiu dosiero estu ligilo kun /etc/resolvconf/run/resolv.conf mem montrante al 127.0.0.1 (dnsmasq). La efektivaj solvantoj devas agordi per /etc/resolv.dnsmasq.conf.",
|
||||||
|
"diagnosis_dns_good_conf": "Bona DNS-agordo por domajno {domain} (kategorio {category})",
|
||||||
|
"diagnosis_dns_bad_conf": "Malbona / mankas DNS-agordo por domajno {domain} (kategorio {category})",
|
||||||
|
"diagnosis_ram_ok": "La sistemo ankoraŭ havas {available} ({available_percent}%) RAM forlasita de {total}.",
|
||||||
|
"diagnosis_swap_none": "La sistemo tute ne havas interŝanĝon. Vi devus pripensi aldoni almenaŭ {recommended} da interŝanĝo por eviti situaciojn en kiuj la sistemo restas sen memoro.",
|
||||||
|
"diagnosis_swap_notsomuch": "La sistemo havas nur {total}-interŝanĝon. Vi konsideru havi almenaŭ {recommended} por eviti situaciojn en kiuj la sistemo restas sen memoro.",
|
||||||
|
"diagnosis_regenconf_manually_modified_details": "Ĉi tio probable estas bona tiel longe kiel vi scias kion vi faras;)!",
|
||||||
|
"diagnosis_regenconf_manually_modified_debian": "Agordodosiero {file} estis modifita permane kompare kun la defaŭlta Debian.",
|
||||||
|
"diagnosis_regenconf_manually_modified_debian_details": "Ĉi tio probable estas bona, sed devas observi ĝin...",
|
||||||
|
"diagnosis_security_all_good": "Neniu kritika sekureca vundebleco estis trovita.",
|
||||||
|
"diagnosis_security_vulnerable_to_meltdown": "Vi ŝajnas vundebla al la kritiko-vundebleco de Meltdown",
|
||||||
|
"diagnosis_no_cache": "Neniu diagnoza kaŝmemoro por kategorio '{category}'",
|
||||||
|
"diagnosis_ip_broken_dnsresolution": "Rezolucio pri domajna nomo rompiĝas pro iu kialo ... Ĉu fajroŝirmilo blokas DNS-petojn ?",
|
||||||
|
"diagnosis_ip_broken_resolvconf": "Rezolucio pri domajna nomo ŝajnas esti rompita en via servilo, kiu ŝajnas rilata al /etc/resolv.conf ne notante 127.0.0.1.",
|
||||||
|
"diagnosis_dns_missing_record": "Laŭ la rekomendita DNS-agordo, vi devas aldoni DNS-registron kun\ntipo: {type}\nnomo: {name}\nvaloro: {value}",
|
||||||
|
"diagnosis_dns_discrepancy": "La DNS-registro kun tipo {type} kaj nomo {name} ne kongruas kun la rekomendita agordo.\nNuna valoro: {current}\nEsceptita valoro: {value}",
|
||||||
|
"diagnosis_services_conf_broken": "Agordo estas rompita por servo {service} !",
|
||||||
|
"diagnosis_services_bad_status": "Servo {service} estas {status} :(",
|
||||||
|
"diagnosis_ram_low": "La sistemo havas {available} ({available_percent}%) RAM forlasita de {total}. Estu zorgema.",
|
||||||
|
"diagnosis_swap_ok": "La sistemo havas {total} da interŝanĝoj!",
|
||||||
|
"diagnosis_mail_ougoing_port_25_ok": "Eliranta haveno 25 ne estas blokita kaj retpoŝto povas esti sendita al aliaj serviloj.",
|
||||||
|
"diagnosis_regenconf_allgood": "Ĉiuj agordaj dosieroj kongruas kun la rekomendita agordo!",
|
||||||
|
"diagnosis_regenconf_manually_modified": "Agordodosiero {file} estis permane modifita.",
|
||||||
|
"diagnosis_description_ip": "Interreta konektebleco",
|
||||||
|
"diagnosis_description_dnsrecords": "Registroj DNS",
|
||||||
|
"diagnosis_description_services": "Servo kontrolas staton",
|
||||||
|
"diagnosis_description_systemresources": "Rimedaj sistemoj",
|
||||||
|
"diagnosis_description_security": "Sekurecaj kontroloj",
|
||||||
|
"diagnosis_ports_could_not_diagnose": "Ne povis diagnozi, ĉu haveblaj havenoj de ekstere.",
|
||||||
|
"diagnosis_ports_could_not_diagnose_details": "Eraro: {error}",
|
||||||
|
"diagnosis_services_bad_status_tip": "Vi povas provi rekomenci la servon, kaj se ĝi ne funkcias, trarigardu la servajn protokolojn uzante 'yunohost service log {service}' aŭ tra la sekcio 'Servoj' de la retadreso.",
|
||||||
|
"diagnosis_security_vulnerable_to_meltdown_details": "Por ripari tion, vi devas ĝisdatigi vian sistemon kaj rekomenci por ŝarĝi la novan linux-kernon (aŭ kontaktu vian servilan provizanton se ĉi tio ne funkcias). Vidu https://meltdownattack.com/ por pliaj informoj.",
|
||||||
|
"diagnosis_description_basesystem": "Baza sistemo",
|
||||||
|
"diagnosis_description_regenconf": "Sistemaj agordoj",
|
||||||
|
"main_domain_change_failed": "Ne eblas ŝanĝi la ĉefan domajnon",
|
||||||
|
"log_domain_main_domain": "Faru '{}' kiel ĉefa domajno",
|
||||||
|
"diagnosis_http_timeout": "Tempolimigita dum provado kontakti vian servilon de ekstere. Ĝi ŝajnas esti neatingebla. Vi devus kontroli, ke vi ĝuste redonas la havenon 80, ke nginx funkcias kaj ke fajroŝirmilo ne interbatalas.",
|
||||||
|
"diagnosis_http_connection_error": "Rilata eraro: ne povis konektiĝi al la petita domajno, tre probable ĝi estas neatingebla.",
|
||||||
|
"migration_description_0013_futureproof_apps_catalog_system": "Migru al la nova katalogosistemo pri estontecaj programoj",
|
||||||
|
"diagnosis_ignored_issues": "(+ {nb_ignored} ignorataj aferoj))",
|
||||||
|
"diagnosis_found_errors": "Trovis {errors} signifa(j) afero(j) rilata al {category}!",
|
||||||
|
"diagnosis_found_errors_and_warnings": "Trovis {errors} signifaj problemo (j) (kaj {warnings} averto) rilataj al {category}!",
|
||||||
|
"diagnosis_diskusage_low": "Stokado {mountpoint} (sur aparato {device)) restas nur {free} ({free_percent}%) spaco. Estu zorgema.",
|
||||||
|
"diagnosis_diskusage_ok": "Stokado {mountpoint} (sur aparato {device) ankoraŭ restas {free} ({free_percent}%) spaco!",
|
||||||
|
"global_settings_setting_pop3_enabled": "Ebligu la protokolon POP3 por la poŝta servilo",
|
||||||
|
"diagnosis_unknown_categories": "La jenaj kategorioj estas nekonataj: {categories}",
|
||||||
|
"diagnosis_services_running": "Servo {service} funkcias!",
|
||||||
|
"diagnosis_ports_unreachable": "Haveno {port} ne atingeblas de ekstere.",
|
||||||
|
"diagnosis_ports_ok": "Haveno {port} atingeblas de ekstere.",
|
||||||
|
"diagnosis_ports_needed_by": "Eksponi ĉi tiun havenon necesas por servo {service}",
|
||||||
|
"diagnosis_ports_forwarding_tip": "Por solvi ĉi tiun problemon, plej probable vi devas agordi la plusendon de haveno en via interreta enkursigilo kiel priskribite en https://yunohost.org/isp_box_config",
|
||||||
|
"diagnosis_http_could_not_diagnose": "Ne povis diagnozi, ĉu atingeblas domajno de ekstere.",
|
||||||
|
"diagnosis_http_could_not_diagnose_details": "Eraro: {error}",
|
||||||
|
"diagnosis_http_ok": "Domajno {domain} atingeblas de ekstere.",
|
||||||
|
"diagnosis_http_unreachable": "Domajno {domain} estas atingebla per HTTP de ekstere.",
|
||||||
|
"domain_cannot_remove_main_add_new_one": "Vi ne povas forigi '{domain:s}' ĉar ĝi estas la ĉefa domajno kaj via sola domajno, vi devas unue aldoni alian domajnon uzante ''yunohost domain add <another-domain.com>', tiam agordi kiel ĉefan domajnon uzante 'yunohost domain main-domain -n <another-domain.com>' kaj tiam vi povas forigi la domajnon' {domain:s} 'uzante' yunohost domain remove {domain:s} '.'",
|
||||||
|
"permission_require_account": "Permesilo {permission} nur havas sencon por uzantoj, kiuj havas konton, kaj tial ne rajtas esti ebligitaj por vizitantoj.",
|
||||||
|
"diagnosis_found_warnings": "Trovitaj {warnings} ero (j) kiuj povus esti plibonigitaj por {category}.",
|
||||||
|
"diagnosis_everything_ok": "Ĉio aspektas bone por {category}!",
|
||||||
|
"diagnosis_failed": "Malsukcesis preni la diagnozan rezulton por kategorio '{category}': {error}",
|
||||||
|
"diagnosis_description_ports": "Ekspoziciaj havenoj",
|
||||||
|
"diagnosis_description_mail": "Retpoŝto",
|
||||||
|
"log_app_action_run": "Funkciigu agon de la apliko '{}'",
|
||||||
|
"log_app_config_show_panel": "Montri la agordan panelon de la apliko '{}'",
|
||||||
|
"log_app_config_apply": "Apliki agordon al la apliko '{}'"
|
||||||
}
|
}
|
||||||
|
|
400
locales/es.json
400
locales/es.json
|
@ -9,82 +9,53 @@
|
||||||
"app_argument_required": "Se requiere el argumento '{name:s} 7'",
|
"app_argument_required": "Se requiere el argumento '{name:s} 7'",
|
||||||
"app_extraction_failed": "No se pudieron extraer los archivos de instalación",
|
"app_extraction_failed": "No se pudieron extraer los archivos de instalación",
|
||||||
"app_id_invalid": "ID de la aplicación no válida",
|
"app_id_invalid": "ID de la aplicación no válida",
|
||||||
"app_incompatible": "La aplicación {app} no es compatible con su versión de YunoHost",
|
|
||||||
"app_install_files_invalid": "Estos archivos no se pueden instalar",
|
"app_install_files_invalid": "Estos archivos no se pueden instalar",
|
||||||
"app_location_already_used": "La aplicación «{app}» ya está instalada en ({path})",
|
|
||||||
"app_location_install_failed": "No se puede instalar la aplicación ahí porque entra en conflicto con la aplicación «{other_app}» ya instalada en «{other_path}»",
|
|
||||||
"app_manifest_invalid": "Algo va mal con el manifiesto de la aplicación: {error}",
|
"app_manifest_invalid": "Algo va mal con el manifiesto de la aplicación: {error}",
|
||||||
"app_no_upgrade": "Todas las aplicaciones están ya actualizadas",
|
|
||||||
"app_not_correctly_installed": "La aplicación {app:s} 8 parece estar incorrectamente instalada",
|
"app_not_correctly_installed": "La aplicación {app:s} 8 parece estar incorrectamente instalada",
|
||||||
"app_not_installed": "No se pudo encontrar la aplicación «{app:s}» en la lista de aplicaciones instaladas: {all_apps}",
|
"app_not_installed": "No se pudo encontrar la aplicación «{app:s}» en la lista de aplicaciones instaladas: {all_apps}",
|
||||||
"app_not_properly_removed": "La {app:s} 0 no ha sido desinstalada correctamente",
|
"app_not_properly_removed": "La {app:s} 0 no ha sido desinstalada correctamente",
|
||||||
"app_package_need_update": "El paquete de la aplicación {app} necesita ser actualizada debido a los cambios en YunoHost",
|
|
||||||
"app_recent_version_required": "{:s} requiere una versión más reciente de moulinette ",
|
|
||||||
"app_removed": "Eliminado {app:s}",
|
"app_removed": "Eliminado {app:s}",
|
||||||
"app_requirements_checking": "Comprobando los paquetes necesarios para {app}…",
|
"app_requirements_checking": "Comprobando los paquetes necesarios para {app}…",
|
||||||
"app_requirements_failed": "No se cumplen algunos requisitos para {app}: {error}",
|
|
||||||
"app_requirements_unmeet": "No se cumplen los requisitos para {app}, el paquete {pkgname} ({version}) debe ser {spec}",
|
"app_requirements_unmeet": "No se cumplen los requisitos para {app}, el paquete {pkgname} ({version}) debe ser {spec}",
|
||||||
"app_sources_fetch_failed": "No se pudieron obtener los archivos con el código fuente, ¿es el URL correcto?",
|
"app_sources_fetch_failed": "No se pudieron obtener los archivos con el código fuente, ¿es el URL correcto?",
|
||||||
"app_unknown": "Aplicación desconocida",
|
"app_unknown": "Aplicación desconocida",
|
||||||
"app_unsupported_remote_type": "Tipo remoto no soportado por la aplicación",
|
"app_unsupported_remote_type": "Tipo remoto no soportado por la aplicación",
|
||||||
"app_upgrade_failed": "No se pudo actualizar {app:s}",
|
"app_upgrade_failed": "No se pudo actualizar {app:s}: {error}",
|
||||||
"app_upgraded": "Actualizado {app:s}",
|
"app_upgraded": "Actualizado {app:s}",
|
||||||
"appslist_fetched": "Obtenida lista de aplicaciones {appslist:s} actualizada",
|
|
||||||
"appslist_removed": "Eliminada la lista de aplicaciones {appslist:s}",
|
|
||||||
"appslist_retrieve_error": "No se puede recuperar la lista remota de aplicaciones {appslist:s}: {error:s}",
|
|
||||||
"appslist_unknown": "Lista de aplicaciones {appslist:s} desconocida.",
|
|
||||||
"ask_current_admin_password": "Contraseña administrativa actual",
|
|
||||||
"ask_email": "Dirección de correo electrónico",
|
"ask_email": "Dirección de correo electrónico",
|
||||||
"ask_firstname": "Nombre",
|
"ask_firstname": "Nombre",
|
||||||
"ask_lastname": "Apellido",
|
"ask_lastname": "Apellido",
|
||||||
"ask_list_to_remove": "Lista para desinstalar",
|
|
||||||
"ask_main_domain": "Dominio principal",
|
"ask_main_domain": "Dominio principal",
|
||||||
"ask_new_admin_password": "Nueva contraseña administrativa",
|
"ask_new_admin_password": "Nueva contraseña administrativa",
|
||||||
"ask_password": "Contraseña",
|
"ask_password": "Contraseña",
|
||||||
"backup_action_required": "Debe especificar algo que guardar",
|
|
||||||
"backup_app_failed": "No se pudo respaldar la aplicación «{app:s}»",
|
"backup_app_failed": "No se pudo respaldar la aplicación «{app:s}»",
|
||||||
"backup_archive_app_not_found": "No se pudo encontrar la aplicación «{app:s}» en el archivo de respaldo",
|
"backup_archive_app_not_found": "No se pudo encontrar la aplicación «{app:s}» en el archivo de respaldo",
|
||||||
"backup_archive_hook_not_exec": "El hook {hook:s} no ha sido ejecutado en esta copia de seguridad",
|
|
||||||
"backup_archive_name_exists": "Ya existe un archivo de respaldo con este nombre.",
|
"backup_archive_name_exists": "Ya existe un archivo de respaldo con este nombre.",
|
||||||
"backup_archive_name_unknown": "Copia de seguridad local desconocida '{name:s}'",
|
"backup_archive_name_unknown": "Copia de seguridad local desconocida '{name:s}'",
|
||||||
"backup_archive_open_failed": "No se pudo abrir el archivo de respaldo",
|
"backup_archive_open_failed": "No se pudo abrir el archivo de respaldo",
|
||||||
"backup_cleaning_failed": "No se pudo limpiar la carpeta de respaldo temporal",
|
"backup_cleaning_failed": "No se pudo limpiar la carpeta de respaldo temporal",
|
||||||
"backup_created": "Se ha creado la copia de seguridad",
|
"backup_created": "Se ha creado la copia de seguridad",
|
||||||
"backup_creating_archive": "Creando el archivo de copia de seguridad…",
|
|
||||||
"backup_creation_failed": "No se pudo crear el archivo de respaldo",
|
"backup_creation_failed": "No se pudo crear el archivo de respaldo",
|
||||||
"backup_delete_error": "No se pudo eliminar «{path:s}»",
|
"backup_delete_error": "No se pudo eliminar «{path:s}»",
|
||||||
"backup_deleted": "Eliminada la copia de seguridad",
|
"backup_deleted": "Eliminada la copia de seguridad",
|
||||||
"backup_extracting_archive": "Extrayendo el archivo de respaldo…",
|
|
||||||
"backup_hook_unknown": "El gancho «{hook:s}» de la copia de seguridad es desconocido",
|
"backup_hook_unknown": "El gancho «{hook:s}» de la copia de seguridad es desconocido",
|
||||||
"backup_invalid_archive": "Esto no es un archivo de respaldo",
|
"backup_invalid_archive": "Esto no es un archivo de respaldo",
|
||||||
"backup_nothings_done": "Nada que guardar",
|
"backup_nothings_done": "Nada que guardar",
|
||||||
"backup_output_directory_forbidden": "Elija un directorio de salida diferente. No se pueden crear copias de seguridad en las subcarpetas de /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var o /home/yunohost.backup/archives",
|
"backup_output_directory_forbidden": "Elija un directorio de salida diferente. No se pueden crear copias de seguridad en las subcarpetas de /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var o /home/yunohost.backup/archives",
|
||||||
"backup_output_directory_not_empty": "Debe elegir un directorio de salida vacío",
|
"backup_output_directory_not_empty": "Debe elegir un directorio de salida vacío",
|
||||||
"backup_output_directory_required": "Debe proporcionar un directorio de salida para la copia de seguridad",
|
"backup_output_directory_required": "Debe proporcionar un directorio de salida para la copia de seguridad",
|
||||||
"backup_running_app_script": "Ejecutando la script de copia de seguridad de la aplicación '{app:s}'...",
|
|
||||||
"backup_running_hooks": "Ejecutando los hooks de copia de seguridad...",
|
"backup_running_hooks": "Ejecutando los hooks de copia de seguridad...",
|
||||||
"custom_app_url_required": "Debe proporcionar una URL para actualizar su aplicación personalizada {app: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 su lista de aplicaciones personalizadas",
|
|
||||||
"diagnosis_debian_version_error": "No se pudo obtener la versión de Debian: {error}",
|
|
||||||
"diagnosis_kernel_version_error": "No se pudo obtener la versión del núcleo: {error}",
|
|
||||||
"diagnosis_monitor_disk_error": "No se pudieron monitorizar los discos: {error}",
|
|
||||||
"diagnosis_monitor_network_error": "No se pudo monitorizar la red: {error}",
|
|
||||||
"diagnosis_monitor_system_error": "No se pudo monitorizar el sistema: {error}",
|
|
||||||
"diagnosis_no_apps": "Aplicación no instalada",
|
|
||||||
"dnsmasq_isnt_installed": "Parece que dnsmasq no está instalado, ejecute «apt-get remove bind9 && apt-get install it»",
|
|
||||||
"domain_cert_gen_failed": "No se pudo generar el certificado",
|
"domain_cert_gen_failed": "No se pudo generar el certificado",
|
||||||
"domain_created": "Dominio creado",
|
"domain_created": "Dominio creado",
|
||||||
"domain_creation_failed": "No se pudo crear el dominio",
|
"domain_creation_failed": "No se pudo crear el dominio {domain}: {error}",
|
||||||
"domain_deleted": "Dominio eliminado",
|
"domain_deleted": "Dominio eliminado",
|
||||||
"domain_deletion_failed": "No se pudo eliminar el dominio",
|
"domain_deletion_failed": "No se pudo eliminar el dominio {domain}: {error}",
|
||||||
"domain_dyndns_already_subscribed": "Ya se ha suscrito a un dominio de DynDNS",
|
"domain_dyndns_already_subscribed": "Ya se ha suscrito a un dominio de DynDNS",
|
||||||
"domain_dyndns_invalid": "Este dominio no se puede usar con DynDNS",
|
|
||||||
"domain_dyndns_root_unknown": "Dominio raíz de DynDNS desconocido",
|
"domain_dyndns_root_unknown": "Dominio raíz de DynDNS desconocido",
|
||||||
"domain_exists": "El dominio ya existe",
|
"domain_exists": "El dominio ya existe",
|
||||||
"domain_uninstall_app_first": "Una o más aplicaciones están instaladas en este dominio. Debe desinstalarlas antes de eliminar el dominio",
|
"domain_uninstall_app_first": "Una o más aplicaciones están instaladas en este dominio. Debe desinstalarlas antes de eliminar el dominio",
|
||||||
"domain_unknown": "Dominio desconocido",
|
"domain_unknown": "Dominio desconocido",
|
||||||
"domain_zone_exists": "El archivo de zona del DNS ya existe",
|
|
||||||
"domain_zone_not_found": "No se ha encontrado el archivo de zona del DNS para el dominio [:s]",
|
|
||||||
"done": "Hecho.",
|
"done": "Hecho.",
|
||||||
"downloading": "Descargando…",
|
"downloading": "Descargando…",
|
||||||
"dyndns_cron_installed": "Creado el trabajo de cron de DynDNS",
|
"dyndns_cron_installed": "Creado el trabajo de cron de DynDNS",
|
||||||
|
@ -104,10 +75,7 @@
|
||||||
"field_invalid": "Campo no válido '{:s}'",
|
"field_invalid": "Campo no válido '{:s}'",
|
||||||
"firewall_reload_failed": "No se pudo recargar el cortafuegos",
|
"firewall_reload_failed": "No se pudo recargar el cortafuegos",
|
||||||
"firewall_reloaded": "Cortafuegos recargado",
|
"firewall_reloaded": "Cortafuegos recargado",
|
||||||
"firewall_rules_cmd_failed": "Algunas órdenes de las reglas del cortafuegos han fallado. Más información en el registro.",
|
"firewall_rules_cmd_failed": "Algunos comandos para aplicar reglas del cortafuegos han fallado. Más información en el registro.",
|
||||||
"format_datetime_short": "%d/%m/%Y %I:%M %p",
|
|
||||||
"hook_argument_missing": "Falta un parámetro '{:s}'",
|
|
||||||
"hook_choice_invalid": "Selección inválida '{:s}'",
|
|
||||||
"hook_exec_failed": "No se pudo ejecutar el guión: {path:s}",
|
"hook_exec_failed": "No se pudo ejecutar el guión: {path:s}",
|
||||||
"hook_exec_not_terminated": "El guión no terminó correctamente:{path:s}",
|
"hook_exec_not_terminated": "El guión no terminó correctamente:{path:s}",
|
||||||
"hook_list_by_invalid": "Esta propiedad no se puede usar para enumerar ganchos («hooks»)",
|
"hook_list_by_invalid": "Esta propiedad no se puede usar para enumerar ganchos («hooks»)",
|
||||||
|
@ -117,98 +85,52 @@
|
||||||
"ip6tables_unavailable": "No puede modificar ip6tables aquí. O bien está en un 'container' o su kernel no soporta esta opción",
|
"ip6tables_unavailable": "No puede modificar ip6tables aquí. O bien está en un 'container' o su kernel no soporta esta opción",
|
||||||
"iptables_unavailable": "No puede modificar iptables aquí. O bien está en un 'container' o su kernel no soporta esta opción",
|
"iptables_unavailable": "No puede modificar iptables aquí. O bien está en un 'container' o su kernel no soporta esta opción",
|
||||||
"ldap_initialized": "Inicializado LDAP",
|
"ldap_initialized": "Inicializado LDAP",
|
||||||
"license_undefined": "indefinido",
|
|
||||||
"mail_alias_remove_failed": "No se pudo eliminar el alias de correo «{mail:s}»",
|
"mail_alias_remove_failed": "No se pudo eliminar el alias de correo «{mail:s}»",
|
||||||
"mail_domain_unknown": "Dirección de correo desconocida para el dominio «{domain:s}»",
|
"mail_domain_unknown": "Dirección de correo no válida para el dominio «{domain:s}». Use un dominio administrado por este servidor.",
|
||||||
"mail_forward_remove_failed": "No se pudo eliminar el reenvío de correo «{mail:s}»",
|
"mail_forward_remove_failed": "No se pudo eliminar el reenvío de correo «{mail:s}»",
|
||||||
"maindomain_change_failed": "No se pudo cambiar el dominio principal",
|
"main_domain_change_failed": "No se pudo cambiar el dominio principal",
|
||||||
"maindomain_changed": "El dominio principal ha cambiado",
|
"main_domain_changed": "El dominio principal ha cambiado",
|
||||||
"monitor_disabled": "Desactivada la monitorización del servidor",
|
|
||||||
"monitor_enabled": "Activada la monitorización del servidor",
|
|
||||||
"monitor_glances_con_failed": "No se pudo conectar al servidor de Glances",
|
|
||||||
"monitor_not_enabled": "La monitorización del servidor está apagada",
|
|
||||||
"monitor_period_invalid": "Período de tiempo no válido",
|
|
||||||
"monitor_stats_file_not_found": "No se pudo encontrar el archivo de estadísticas",
|
|
||||||
"monitor_stats_no_update": "No hay estadísticas de monitorización para actualizar",
|
|
||||||
"monitor_stats_period_unavailable": "No hay estadísticas para el período",
|
|
||||||
"mountpoint_unknown": "Punto de montaje desconocido",
|
|
||||||
"mysql_db_creation_failed": "Error al crear la base de datos de MySQL",
|
|
||||||
"mysql_db_init_failed": "Error al iniciar la base de datos de MySQL",
|
|
||||||
"mysql_db_initialized": "Inicializada la base de datos MySQL",
|
|
||||||
"network_check_mx_ko": "El registro DNS MX no está configurado",
|
|
||||||
"network_check_smtp_ko": "El correo saliente (SMTP puerto 25) parece estar bloqueado por su red",
|
|
||||||
"network_check_smtp_ok": "El correo saliente (SMTP puerto 25) no está bloqueado",
|
|
||||||
"new_domain_required": "Debe proporcionar el nuevo dominio principal",
|
|
||||||
"no_appslist_found": "No se ha encontrado ninguna lista de aplicaciones",
|
|
||||||
"no_internet_connection": "El servidor no está conectado a Internet",
|
"no_internet_connection": "El servidor no está conectado a Internet",
|
||||||
"no_ipv6_connectivity": "La conexión por IPv6 no está disponible",
|
|
||||||
"no_restore_script": "No se ha encontrado un script de restauración para la aplicación '{app:s}'",
|
|
||||||
"not_enough_disk_space": "No hay espacio libre suficiente en «{path:s}»",
|
"not_enough_disk_space": "No hay espacio libre suficiente en «{path:s}»",
|
||||||
"package_not_installed": "El paquete '{pkgname}' no está instalado",
|
|
||||||
"package_unexpected_error": "Ha ocurrido un error inesperado procesando el paquete '{pkgname}'",
|
|
||||||
"package_unknown": "Paquete desconocido '{pkgname}'",
|
"package_unknown": "Paquete desconocido '{pkgname}'",
|
||||||
"packages_no_upgrade": "No hay paquetes para actualizar",
|
|
||||||
"packages_upgrade_critical_later": "Los paquetes críticos ({packages:s}) serán actualizados más tarde",
|
|
||||||
"packages_upgrade_failed": "No se pudieron actualizar todos los paquetes",
|
"packages_upgrade_failed": "No se pudieron actualizar todos los paquetes",
|
||||||
"path_removal_failed": "No se pudo eliminar la ruta {:s}",
|
|
||||||
"pattern_backup_archive_name": "Debe ser un nombre de archivo válido con un máximo de 30 caracteres, solo se admiten caracteres alfanuméricos y los caracteres -_. (guiones y punto)",
|
"pattern_backup_archive_name": "Debe ser un nombre de archivo válido con un máximo de 30 caracteres, solo se admiten caracteres alfanuméricos y los caracteres -_. (guiones y punto)",
|
||||||
"pattern_domain": "El nombre de dominio debe ser válido (por ejemplo mi-dominio.org)",
|
"pattern_domain": "El nombre de dominio debe ser válido (por ejemplo mi-dominio.org)",
|
||||||
"pattern_email": "Debe ser una dirección de correo electrónico válida (por ejemplo, alguien@dominio.org)",
|
"pattern_email": "Debe ser una dirección de correo electrónico válida (p.ej. alguien@example.com)",
|
||||||
"pattern_firstname": "Debe ser un nombre válido",
|
"pattern_firstname": "Debe ser un nombre válido",
|
||||||
"pattern_lastname": "Debe ser un apellido válido",
|
"pattern_lastname": "Debe ser un apellido válido",
|
||||||
"pattern_listname": "Solo se pueden usar caracteres alfanuméricos y el guion bajo",
|
|
||||||
"pattern_mailbox_quota": "Debe ser un tamaño con el sufijo «b/k/M/G/T» o «0» para no tener una cuota",
|
"pattern_mailbox_quota": "Debe ser un tamaño con el sufijo «b/k/M/G/T» o «0» para no tener una cuota",
|
||||||
"pattern_password": "Debe contener al menos 3 caracteres",
|
"pattern_password": "Debe contener al menos 3 caracteres",
|
||||||
"pattern_port": "Debe ser un número de puerto válido (es decir, entre 0-65535)",
|
|
||||||
"pattern_port_or_range": "Debe ser un número de puerto válido (es decir entre 0-65535) o un intervalo de puertos (por ejemplo 100:200)",
|
"pattern_port_or_range": "Debe ser un número de puerto válido (es decir entre 0-65535) o un intervalo de puertos (por ejemplo 100:200)",
|
||||||
"pattern_positive_number": "Deber ser un número positivo",
|
"pattern_positive_number": "Deber ser un número positivo",
|
||||||
"pattern_username": "Solo puede contener caracteres alfanuméricos o el guión bajo",
|
"pattern_username": "Solo puede contener caracteres alfanuméricos o el guión bajo",
|
||||||
"port_already_closed": "El puerto {port:d} ya está cerrado para las conexiones {ip_version:s}",
|
"port_already_closed": "El puerto {port:d} ya está cerrado para las conexiones {ip_version:s}",
|
||||||
"port_already_opened": "El puerto {port:d} ya está abierto para las conexiones {ip_version:s}",
|
"port_already_opened": "El puerto {port:d} ya está abierto para las conexiones {ip_version:s}",
|
||||||
"port_available": "El puerto {port:d} está disponible",
|
|
||||||
"port_unavailable": "El puerto {port:d} no está disponible",
|
|
||||||
"restore_action_required": "Debe escoger algo que restaurar",
|
|
||||||
"restore_already_installed_app": "Una aplicación con el ID «{app:s}» ya está instalada",
|
"restore_already_installed_app": "Una aplicación con el ID «{app:s}» ya está instalada",
|
||||||
"restore_app_failed": "No se pudo restaurar la aplicación «{app:s}»",
|
"restore_app_failed": "No se pudo restaurar la aplicación «{app:s}»",
|
||||||
"restore_cleaning_failed": "No se pudo limpiar el directorio temporal de restauración",
|
"restore_cleaning_failed": "No se pudo limpiar el directorio temporal de restauración",
|
||||||
"restore_complete": "Restaurada",
|
"restore_complete": "Restaurada",
|
||||||
"restore_confirm_yunohost_installed": "¿Realmente desea restaurar un sistema ya instalado? [{answers:s}]",
|
"restore_confirm_yunohost_installed": "¿Realmente desea restaurar un sistema ya instalado? [{answers:s}]",
|
||||||
"restore_failed": "No se pudo restaurar el sistema",
|
"restore_failed": "No se pudo restaurar el sistema",
|
||||||
"restore_hook_unavailable": "El guión de restauración para «{part:s}» no está disponible en su sistema y tampoco en el archivo",
|
"restore_hook_unavailable": "El script de restauración para «{part:s}» no está disponible en su sistema y tampoco en el archivo",
|
||||||
"restore_nothings_done": "No se ha restaurado nada",
|
"restore_nothings_done": "No se ha restaurado nada",
|
||||||
"restore_running_app_script": "Restaurando la aplicación «{app:s}»…",
|
"restore_running_app_script": "Restaurando la aplicación «{app:s}»…",
|
||||||
"restore_running_hooks": "Ejecutando los ganchos de restauración…",
|
"restore_running_hooks": "Ejecutando los ganchos de restauración…",
|
||||||
"service_add_failed": "No se pudo añadir el servicio «{service:s}»",
|
"service_add_failed": "No se pudo añadir el servicio «{service:s}»",
|
||||||
"service_added": "Añadido el servicio «{service:s}»",
|
"service_added": "Añadido el servicio «{service:s}»",
|
||||||
"service_already_started": "El servicio «{service:s}» ya ha sido iniciado",
|
"service_already_started": "El servicio «{service:s}» ya está funcionando",
|
||||||
"service_already_stopped": "El servicio «{service:s}» ya ha sido detenido",
|
"service_already_stopped": "El servicio «{service:s}» ya ha sido detenido",
|
||||||
"service_cmd_exec_failed": "No se pudo ejecutar la orden «{command:s}»",
|
"service_cmd_exec_failed": "No se pudo ejecutar la orden «{command:s}»",
|
||||||
"service_conf_file_backed_up": "Se ha realizado una copia de seguridad del archivo de configuración '{conf}' en '{backup}'",
|
|
||||||
"service_conf_file_copy_failed": "No se puede copiar el nuevo archivo de configuración '{new}' a {conf}",
|
|
||||||
"service_conf_file_manually_modified": "El archivo de configuración '{conf}' ha sido modificado manualmente y no será actualizado",
|
|
||||||
"service_conf_file_manually_removed": "El archivo de configuración '{conf}' ha sido eliminado manualmente y no será creado",
|
|
||||||
"service_conf_file_not_managed": "El archivo de configuración '{conf}' no está gestionado y no será actualizado",
|
|
||||||
"service_conf_file_remove_failed": "No se puede eliminar el archivo de configuración '{conf}'",
|
|
||||||
"service_conf_file_removed": "El archivo de configuración '{conf}' ha sido eliminado",
|
|
||||||
"service_conf_file_updated": "El archivo de configuración '{conf}' ha sido actualizado",
|
|
||||||
"service_conf_up_to_date": "La configuración del servicio '{service}' ya está actualizada",
|
|
||||||
"service_conf_updated": "La configuración ha sido actualizada para el servicio '{service}'",
|
|
||||||
"service_conf_would_be_updated": "La configuración podría haber sido actualizada para el servicio '{service} 1'",
|
|
||||||
"service_disable_failed": "No se pudo desactivar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
"service_disable_failed": "No se pudo desactivar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
||||||
"service_disabled": "Desactivado el servicio «{service:s}»",
|
"service_disabled": "El servicio «{service:s}» ha sido desactivado",
|
||||||
"service_enable_failed": "No se pudo activar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
"service_enable_failed": "No se pudo activar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
||||||
"service_enabled": "Activado el servicio «{service:s}»",
|
"service_enabled": "El servicio «{service:s}» ha sido desactivado",
|
||||||
"service_no_log": "No hay ningún registro para el servicio '{service:s}'",
|
|
||||||
"service_regenconf_dry_pending_applying": "Comprobando configuración pendiente que podría haber sido aplicada al servicio '{service}'...",
|
|
||||||
"service_regenconf_failed": "No se puede regenerar la configuración para el servicio(s): {services}",
|
|
||||||
"service_regenconf_pending_applying": "Aplicando la configuración pendiente para el servicio '{service}'...",
|
|
||||||
"service_remove_failed": "No se pudo eliminar el servicio «{service:s}»",
|
"service_remove_failed": "No se pudo eliminar el servicio «{service:s}»",
|
||||||
"service_removed": "Eliminado el servicio «{service:s}»",
|
"service_removed": "Eliminado el servicio «{service:s}»",
|
||||||
"service_start_failed": "No se pudo iniciar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
"service_start_failed": "No se pudo iniciar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
||||||
"service_started": "Iniciado el servicio «{service:s}»",
|
"service_started": "Iniciado el servicio «{service:s}»",
|
||||||
"service_status_failed": "No se pudo determinar el estado del servicio «{service:s}»",
|
|
||||||
"service_stop_failed": "No se pudo detener el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
"service_stop_failed": "No se pudo detener el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
||||||
"service_stopped": "Detenido el servicio «{service:s}»",
|
"service_stopped": "El servicio «{service:s}» se detuvo",
|
||||||
"service_unknown": "Servicio desconocido '{service:s}'",
|
"service_unknown": "Servicio desconocido '{service:s}'",
|
||||||
"ssowat_conf_generated": "Generada la configuración de SSOwat",
|
"ssowat_conf_generated": "Generada la configuración de SSOwat",
|
||||||
"ssowat_conf_updated": "Actualizada la configuración de SSOwat",
|
"ssowat_conf_updated": "Actualizada la configuración de SSOwat",
|
||||||
|
@ -216,10 +138,8 @@
|
||||||
"system_username_exists": "El nombre de usuario ya existe en la lista de usuarios del sistema",
|
"system_username_exists": "El nombre de usuario ya existe en la lista de usuarios del sistema",
|
||||||
"unbackup_app": "La aplicación '{app:s}' no se guardará",
|
"unbackup_app": "La aplicación '{app:s}' no se guardará",
|
||||||
"unexpected_error": "Algo inesperado salió mal: {error}",
|
"unexpected_error": "Algo inesperado salió mal: {error}",
|
||||||
"unit_unknown": "Unidad desconocida '{unit:s}'",
|
|
||||||
"unlimit": "Sin cuota",
|
"unlimit": "Sin cuota",
|
||||||
"unrestore_app": "La aplicación '{app:s}' no será restaurada",
|
"unrestore_app": "La aplicación '{app:s}' no será restaurada",
|
||||||
"update_cache_failed": "No se pudo actualizar la caché de APT",
|
|
||||||
"updating_apt_cache": "Obteniendo las actualizaciones disponibles para los paquetes del sistema…",
|
"updating_apt_cache": "Obteniendo las actualizaciones disponibles para los paquetes del sistema…",
|
||||||
"upgrade_complete": "Actualización finalizada",
|
"upgrade_complete": "Actualización finalizada",
|
||||||
"upgrading_packages": "Actualizando paquetes…",
|
"upgrading_packages": "Actualizando paquetes…",
|
||||||
|
@ -228,23 +148,20 @@
|
||||||
"upnp_enabled": "UPnP activado",
|
"upnp_enabled": "UPnP activado",
|
||||||
"upnp_port_open_failed": "No se pudo abrir el puerto vía UPnP",
|
"upnp_port_open_failed": "No se pudo abrir el puerto vía UPnP",
|
||||||
"user_created": "Usuario creado",
|
"user_created": "Usuario creado",
|
||||||
"user_creation_failed": "No se pudo crear el usuario",
|
"user_creation_failed": "No se pudo crear el usuario {user}: {error}",
|
||||||
"user_deleted": "Usuario eliminado",
|
"user_deleted": "Usuario eliminado",
|
||||||
"user_deletion_failed": "No se pudo eliminar el usuario",
|
"user_deletion_failed": "No se pudo eliminar el usuario {user}: {error}",
|
||||||
"user_home_creation_failed": "No se pudo crear la carpeta «home» para el usuario",
|
"user_home_creation_failed": "No se pudo crear la carpeta «home» para el usuario",
|
||||||
"user_info_failed": "No se pudo obtener la información del usuario",
|
|
||||||
"user_unknown": "Usuario desconocido: {user:s}",
|
"user_unknown": "Usuario desconocido: {user:s}",
|
||||||
"user_update_failed": "No se pudo cambiar la información del usuario",
|
"user_update_failed": "No se pudo actualizar el usuario {user}: {error}",
|
||||||
"user_updated": "Cambiada la información de usuario",
|
"user_updated": "Cambiada la información de usuario",
|
||||||
"yunohost_already_installed": "YunoHost ya está instalado",
|
"yunohost_already_installed": "YunoHost ya está instalado",
|
||||||
"yunohost_ca_creation_failed": "No se pudo crear la autoridad de certificación",
|
"yunohost_ca_creation_failed": "No se pudo crear la autoridad de certificación",
|
||||||
"yunohost_configured": "YunoHost está configurado",
|
"yunohost_configured": "YunoHost está ahora configurado",
|
||||||
"yunohost_installing": "Instalando YunoHost…",
|
"yunohost_installing": "Instalando YunoHost…",
|
||||||
"yunohost_not_installed": "YunoHost no está correctamente instalado. Ejecute «yunohost tools postinstall»",
|
"yunohost_not_installed": "YunoHost no está correctamente instalado. Ejecute «yunohost tools postinstall»",
|
||||||
"ldap_init_failed_to_create_admin": "La inicialización de LDAP no pudo crear el usuario «admin»",
|
"ldap_init_failed_to_create_admin": "La inicialización de LDAP no pudo crear el usuario «admin»",
|
||||||
"mailbox_used_space_dovecot_down": "El servicio de correo Dovecot debe estar funcionando si desea obtener el espacio usado por el buzón de correo",
|
"mailbox_used_space_dovecot_down": "El servicio de correo Dovecot debe estar funcionando si desea obtener el espacio usado por el buzón de correo",
|
||||||
"ssowat_persistent_conf_read_error": "No se pudo leer la configuración persistente de SSOwat: {error:s}. Edite el archivo /etc/ssowat/conf.json.persistent para corregir la sintaxis de JSON",
|
|
||||||
"ssowat_persistent_conf_write_error": "No se pudo guardar la configuración persistente de SSOwat: {error:s}. Edite el archivo /etc/ssowat/conf.json.persistent para corregir la sintaxis de JSON",
|
|
||||||
"certmanager_attempt_to_replace_valid_cert": "Está intentando sobrescribir un certificado correcto y válido para el dominio {domain:s}! (Use --force para omitir este mensaje)",
|
"certmanager_attempt_to_replace_valid_cert": "Está intentando sobrescribir un certificado correcto y válido para el dominio {domain:s}! (Use --force para omitir este mensaje)",
|
||||||
"certmanager_domain_unknown": "Dominio desconocido «{domain:s}»",
|
"certmanager_domain_unknown": "Dominio desconocido «{domain:s}»",
|
||||||
"certmanager_domain_cert_not_selfsigned": "El certificado para el dominio {domain:s} no es un certificado autofirmado. ¿Está seguro de que quiere reemplazarlo? (Use «--force» para hacerlo)",
|
"certmanager_domain_cert_not_selfsigned": "El certificado para el dominio {domain:s} no es un certificado autofirmado. ¿Está seguro de que quiere reemplazarlo? (Use «--force» para hacerlo)",
|
||||||
|
@ -258,50 +175,38 @@
|
||||||
"certmanager_cert_install_success_selfsigned": "Instalado correctamente un certificado autofirmado para el dominio «{domain:s}»",
|
"certmanager_cert_install_success_selfsigned": "Instalado correctamente un certificado autofirmado para el dominio «{domain:s}»",
|
||||||
"certmanager_cert_install_success": "Instalado correctamente un certificado de Let's Encrypt para el dominio «{domain:s}»",
|
"certmanager_cert_install_success": "Instalado correctamente un certificado de Let's Encrypt para el dominio «{domain:s}»",
|
||||||
"certmanager_cert_renew_success": "Renovado correctamente el certificado de Let's Encrypt para el dominio «{domain:s}»",
|
"certmanager_cert_renew_success": "Renovado correctamente el certificado de Let's Encrypt para el dominio «{domain:s}»",
|
||||||
"certmanager_old_letsencrypt_app_detected": "\nYunohost ha detectado que la aplicación 'letsencrypt' está instalada, esto produce conflictos con las nuevas funciones de administración de certificados integradas en Yunohost. Si desea utilizar las nuevas funciones integradas, ejecute los siguientes comandos para migrar su instalación:\n\n Yunohost app remove letsencrypt\n Yunohost domain cert-install\n\nP.D.: esto intentará reinstalar los certificados para todos los dominios con un certificado Let's Encrypt o con un certificado autofirmado",
|
|
||||||
"certmanager_hit_rate_limit": "Se han emitido demasiados certificados recientemente para este conjunto exacto de dominios {domain:s}. Pruebe de nuevo más tarde. Vea para más detalles https://letsencrypt.org/docs/rate-limits/",
|
"certmanager_hit_rate_limit": "Se han emitido demasiados certificados recientemente para este conjunto exacto de dominios {domain:s}. Pruebe de nuevo más tarde. Vea para más detalles https://letsencrypt.org/docs/rate-limits/",
|
||||||
"certmanager_cert_signing_failed": "No se pudo firmar el nuevo certificado",
|
"certmanager_cert_signing_failed": "No se pudo firmar el nuevo certificado",
|
||||||
"certmanager_no_cert_file": "No se pudo leer el certificado para el dominio {domain:s} (archivo: {file:s})",
|
"certmanager_no_cert_file": "No se pudo leer el certificado para el dominio {domain:s} (archivo: {file:s})",
|
||||||
"certmanager_conflicting_nginx_file": "No se pudo preparar el dominio para el desafío ACME: el archivo de configuración de NGINX {filepath:s} está en conflicto y debe ser eliminado primero",
|
"certmanager_conflicting_nginx_file": "No se pudo preparar el dominio para el desafío ACME: el archivo de configuración de NGINX {filepath:s} está en conflicto y debe ser eliminado primero",
|
||||||
"domain_cannot_remove_main": "No se puede eliminar el dominio principal. Configure uno primero",
|
"domain_cannot_remove_main": "No se puede eliminar el dominio principal. Primero debes configurar otro utilizando la linea de comando 'yunohost domain main-domain -n <otro_dominio>' donde <otro_dominio> es parte de esta lista: {other_domains:s}",
|
||||||
"certmanager_self_ca_conf_file_not_found": "No se pudo encontrar el archivo de configuración para la autoridad de autofirma (archivo: {file:s})",
|
"certmanager_self_ca_conf_file_not_found": "No se pudo encontrar el archivo de configuración para la autoridad de autofirma (archivo: {file:s})",
|
||||||
"certmanager_unable_to_parse_self_CA_name": "No se pudo procesar el nombre de la autoridad de autofirma (archivo: {file:s})",
|
"certmanager_unable_to_parse_self_CA_name": "No se pudo procesar el nombre de la autoridad de autofirma (archivo: {file:s})",
|
||||||
"domains_available": "Dominios disponibles:",
|
"domains_available": "Dominios disponibles:",
|
||||||
"backup_archive_broken_link": "No se pudo acceder al archivo de respaldo (enlace roto a {path:s})",
|
"backup_archive_broken_link": "No se pudo acceder al archivo de respaldo (enlace roto a {path:s})",
|
||||||
"certmanager_domain_not_resolved_locally": "El dominio {domain:s} no puede ser resuelto desde su servidor de YunoHost. Esto puede suceder si ha modificado su registro DNS recientemente. De ser así, espere unas horas para que se propague. Si el problema continúa, considere añadir {domain:s} a /etc/hosts. (Si sabe lo que está haciendo, use «--no-checks» para desactivar esas comprobaciones.)",
|
|
||||||
"certmanager_acme_not_configured_for_domain": "El certificado para el dominio «{domain:s}» no parece que esté instalado correctamente. Ejecute primero «cert-install» para este dominio.",
|
"certmanager_acme_not_configured_for_domain": "El certificado para el dominio «{domain:s}» no parece que esté instalado correctamente. Ejecute primero «cert-install» para este dominio.",
|
||||||
"certmanager_http_check_timeout": "Tiempo de espera agotado cuando el servidor intentaba conectarse consigo mismo a través de HTTP usando una dirección IP pública (dominio «{domain:s}» con IP «{ip:s}»). Puede que esté experimentando un problema de redirección («hairpinning»), o que el cortafuegos o el enrutador de su servidor esté mal configurado.",
|
"certmanager_http_check_timeout": "Tiempo de espera agotado cuando el servidor intentaba conectarse consigo mismo a través de HTTP usando una dirección IP pública (dominio «{domain:s}» con IP «{ip:s}»). Puede que esté experimentando un problema de redirección («hairpinning»), o que el cortafuegos o el enrutador de su servidor esté mal configurado.",
|
||||||
"certmanager_couldnt_fetch_intermediate_cert": "Tiempo de espera agotado intentando obtener el certificado intermedio de Let's Encrypt. Cancelada la instalación o renovación del certificado. Vuelva a intentarlo más tarde.",
|
"certmanager_couldnt_fetch_intermediate_cert": "Tiempo de espera agotado intentando obtener el certificado intermedio de Let's Encrypt. Cancelada la instalación o renovación del certificado. Vuelva a intentarlo más tarde.",
|
||||||
"appslist_retrieve_bad_format": "No se pudo leer la lista de aplicaciones obtenida {appslist:s}",
|
|
||||||
"domain_hostname_failed": "No se pudo establecer un nuevo nombre de anfitrión («hostname»). Esto podría causar problemas más tarde (no es seguro... podría ir bien).",
|
"domain_hostname_failed": "No se pudo establecer un nuevo nombre de anfitrión («hostname»). Esto podría causar problemas más tarde (no es seguro... podría ir bien).",
|
||||||
"yunohost_ca_creation_success": "Creada la autoridad de certificación local.",
|
"yunohost_ca_creation_success": "Creada la autoridad de certificación local.",
|
||||||
"app_already_installed_cant_change_url": "Esta aplicación ya está instalada. No se puede cambiar el URL únicamente mediante esta función. Compruebe si está disponible la opción `app changeurl`.",
|
"app_already_installed_cant_change_url": "Esta aplicación ya está instalada. No se puede cambiar el URL únicamente mediante esta función. Compruebe si está disponible la opción `app changeurl`.",
|
||||||
"app_change_no_change_url_script": "La aplicacion {app_name:s} aún no permite cambiar su URL, es posible que deba actualizarla.",
|
|
||||||
"app_change_url_failed_nginx_reload": "No se pudo recargar NGINX. Esta es la salida de «nginx -t»:\n{nginx_errors:s}",
|
"app_change_url_failed_nginx_reload": "No se pudo recargar NGINX. Esta es la salida de «nginx -t»:\n{nginx_errors:s}",
|
||||||
"app_change_url_identical_domains": "El antiguo y nuevo dominio/url_path son idénticos ('{domain:s} {path:s}'), no se realizarán cambios.",
|
"app_change_url_identical_domains": "El antiguo y nuevo dominio/url_path son idénticos ('{domain:s} {path:s}'), no se realizarán cambios.",
|
||||||
"app_change_url_no_script": "Esta aplicación «{app_name:s}» aún no permite la modificación de URLs. Quizás debería actualizarla.",
|
"app_change_url_no_script": "La aplicación «{app_name:s}» aún no permite la modificación de URLs. Quizás debería actualizarla.",
|
||||||
"app_change_url_success": "El URL de la aplicación {app:s} es ahora {domain:s} {path:s}",
|
"app_change_url_success": "El URL de la aplicación {app:s} es ahora {domain:s} {path:s}",
|
||||||
"app_location_unavailable": "Este URL o no está disponible o está en conflicto con otra(s) aplicación(es) instalada(s):\n{apps:s}",
|
"app_location_unavailable": "Este URL o no está disponible o está en conflicto con otra(s) aplicación(es) instalada(s):\n{apps:s}",
|
||||||
"app_already_up_to_date": "La aplicación {app:s} ya está actualizada",
|
"app_already_up_to_date": "La aplicación {app:s} ya está actualizada",
|
||||||
"appslist_name_already_tracked": "Ya existe una lista de aplicaciones registradas con el nombre {name:s}.",
|
|
||||||
"appslist_url_already_tracked": "Ya existe una lista de aplicaciones registradas con el URL {url:s}.",
|
|
||||||
"appslist_migrating": "Migrando la lista de aplicaciones {appslist:s}…",
|
|
||||||
"appslist_could_not_migrate": "¡No se pudo migrar la lista de aplicaciones {appslist:s}! No se pudo analizar el URL… El antiguo trabajo de cron se mantuvo en {bkp_file:s}.",
|
|
||||||
"appslist_corrupted_json": "No se pudieron cargar las listas de aplicaciones. Parece que {filename:s} está dañado.",
|
|
||||||
"invalid_url_format": "Algo va mal con el URL",
|
|
||||||
"app_upgrade_some_app_failed": "No se pudieron actualizar algunas aplicaciones",
|
"app_upgrade_some_app_failed": "No se pudieron actualizar algunas aplicaciones",
|
||||||
"app_make_default_location_already_used": "No puede hacer que la aplicación «{app}» sea la predeterminada en el dominio, {domain} ya está siendo usado por otra aplicación «{other_app}»",
|
"app_make_default_location_already_used": "No puede hacer que la aplicación «{app}» sea la predeterminada en el dominio, «{domain}» ya está siendo usado por otra aplicación «{other_app}»",
|
||||||
"app_upgrade_app_name": "Actualizando ahora {app}…",
|
"app_upgrade_app_name": "Actualizando ahora {app}…",
|
||||||
"ask_path": "Camino",
|
|
||||||
"backup_abstract_method": "Este método de respaldo aún no se ha implementado",
|
"backup_abstract_method": "Este método de respaldo aún no se ha implementado",
|
||||||
"backup_applying_method_borg": "Enviando todos los archivos para la copia de seguridad al repositorio de borg-backup…",
|
"backup_applying_method_borg": "Enviando todos los archivos para la copia de seguridad al repositorio de borg-backup…",
|
||||||
"backup_applying_method_copy": "Copiando todos los archivos a la copia de seguridad…",
|
"backup_applying_method_copy": "Copiando todos los archivos a la copia de seguridad…",
|
||||||
"backup_applying_method_custom": "Llamando al método de copia de seguridad personalizado «{method:s}»…",
|
"backup_applying_method_custom": "Llamando al método de copia de seguridad personalizado «{method:s}»…",
|
||||||
"backup_applying_method_tar": "Creando el archivo TAR de respaldo…",
|
"backup_applying_method_tar": "Creando el archivo TAR de respaldo…",
|
||||||
"backup_archive_mount_failed": "No se pudo montar el archivo de respaldo",
|
|
||||||
"backup_archive_system_part_not_available": "La parte del sistema «{part:s}» no está disponible en esta copia de seguridad",
|
"backup_archive_system_part_not_available": "La parte del sistema «{part:s}» no está disponible en esta copia de seguridad",
|
||||||
"backup_archive_writing_error": "No se pudieron añadir los archivos «{source:s}» (llamados en el archivo «{dest:s}») para ser respaldados en el archivo comprimido «{archive:s}»",
|
"backup_archive_writing_error": "No se pudieron añadir los archivos «{source:s}» (llamados en el archivo «{dest:s}») para ser respaldados en el archivo comprimido «{archive:s}»",
|
||||||
"backup_ask_for_copying_if_needed": "No se pudieron preparar algunos archivos para la copia de seguridad usando el método que evita desperdiciar espacio temporalmente en el sistema. Para hacer la copia de seguridad, {size:s}MB se usarán temporalmente. ¿Está de acuerdo?",
|
"backup_ask_for_copying_if_needed": "¿Quiere realizar la copia de seguridad usando {size:s} MB temporalmente? (Se usa este modo ya que algunos archivos no se pudieron preparar usando un método más eficiente.)",
|
||||||
"backup_borg_not_implemented": "El método de respaldo de Borg aún no ha sido implementado",
|
"backup_borg_not_implemented": "El método de respaldo de Borg aún no ha sido implementado",
|
||||||
"backup_cant_mount_uncompress_archive": "No se pudo montar el archivo descomprimido como protegido contra escritura",
|
"backup_cant_mount_uncompress_archive": "No se pudo montar el archivo descomprimido como protegido contra escritura",
|
||||||
"backup_copying_to_organize_the_archive": "Copiando {size:s}MB para organizar el archivo",
|
"backup_copying_to_organize_the_archive": "Copiando {size:s}MB para organizar el archivo",
|
||||||
|
@ -309,7 +214,6 @@
|
||||||
"backup_csv_addition_failed": "No se pudo añadir archivos para respaldar en el archivo CSV",
|
"backup_csv_addition_failed": "No se pudo añadir archivos para respaldar en el archivo CSV",
|
||||||
"backup_csv_creation_failed": "No se pudo crear el archivo CSV necesario para la restauración",
|
"backup_csv_creation_failed": "No se pudo crear el archivo CSV necesario para la restauración",
|
||||||
"backup_custom_mount_error": "El método de respaldo personalizado no pudo superar el paso «mount»",
|
"backup_custom_mount_error": "El método de respaldo personalizado no pudo superar el paso «mount»",
|
||||||
"backup_custom_need_mount_error": "El método de respaldo personalizado no pudo superar el paso «need_mount»",
|
|
||||||
"backup_no_uncompress_archive_dir": "No existe tal directorio de archivos sin comprimir",
|
"backup_no_uncompress_archive_dir": "No existe tal directorio de archivos sin comprimir",
|
||||||
"backup_php5_to_php7_migration_may_fail": "No se pudo convertir su archivo para que sea compatible con PHP 7, puede que no pueda restaurar sus aplicaciones de PHP (motivo: {error:s})",
|
"backup_php5_to_php7_migration_may_fail": "No se pudo convertir su archivo para que sea compatible con PHP 7, puede que no pueda restaurar sus aplicaciones de PHP (motivo: {error:s})",
|
||||||
"backup_system_part_failed": "No se pudo respaldar la parte del sistema «{part:s}»",
|
"backup_system_part_failed": "No se pudo respaldar la parte del sistema «{part:s}»",
|
||||||
|
@ -320,33 +224,28 @@
|
||||||
"experimental_feature": "Aviso : esta funcionalidad es experimental y no se considera estable, no debería usarla a menos que sepa lo que está haciendo.",
|
"experimental_feature": "Aviso : esta funcionalidad es experimental y no se considera estable, no debería usarla a menos que sepa lo que está haciendo.",
|
||||||
"good_practices_about_user_password": "Está a punto de establecer una nueva contraseña de usuario. La contraseña debería de ser de al menos 8 caracteres, aunque es una buena práctica usar una contraseña más extensa (básicamente una frase) y/o usar caracteres de varias clases (mayúsculas, minúsculas, números y caracteres especiales).",
|
"good_practices_about_user_password": "Está a punto de establecer una nueva contraseña de usuario. La contraseña debería de ser de al menos 8 caracteres, aunque es una buena práctica usar una contraseña más extensa (básicamente una frase) y/o usar caracteres de varias clases (mayúsculas, minúsculas, números y caracteres especiales).",
|
||||||
"password_listed": "Esta contraseña es una de las más usadas en el mundo. Elija algo más único.",
|
"password_listed": "Esta contraseña es una de las más usadas en el mundo. Elija algo más único.",
|
||||||
"password_too_simple_1": "La contraseña tiene que ser de al menos 8 caracteres de longitud",
|
"password_too_simple_1": "La contraseña debe tener al menos 8 caracteres de longitud",
|
||||||
"password_too_simple_2": "La contraseña tiene que ser de al menos 8 caracteres de longitud e incluir un número y caracteres en mayúsculas y minúsculas",
|
"password_too_simple_2": "La contraseña tiene que ser de al menos 8 caracteres de longitud e incluir un número y caracteres en mayúsculas y minúsculas",
|
||||||
"password_too_simple_3": "La contraseña tiene que ser de al menos 8 caracteres de longitud e incluir un número, mayúsculas, minúsculas y caracteres especiales",
|
"password_too_simple_3": "La contraseña tiene que ser de al menos 8 caracteres de longitud e incluir un número, mayúsculas, minúsculas y caracteres especiales",
|
||||||
"password_too_simple_4": "La contraseña tiene que ser de al menos 12 caracteres de longitud e incluir un número, mayúsculas, minúsculas y caracteres especiales",
|
"password_too_simple_4": "La contraseña tiene que ser de al menos 12 caracteres de longitud e incluir un número, mayúsculas, minúsculas y caracteres especiales",
|
||||||
"users_available": "Usuarios disponibles:",
|
"users_available": "Usuarios disponibles:",
|
||||||
"user_not_in_group": "El usuario «{user:s}» no está en el grupo «{group:s}»",
|
|
||||||
"user_already_in_group": "El usuario «{user:}» ya está en el grupo «{group:s}»",
|
|
||||||
"updating_app_lists": "Obteniendo actualizaciones disponibles para las aplicaciones…",
|
|
||||||
"update_apt_cache_warning": "Algo fue mal durante la actualización de la caché de APT (gestor de paquetes de Debian). Aquí tiene un volcado de las líneas de sources.list que podría ayudarle a identificar las líneas problemáticas:\n{sourceslist}",
|
"update_apt_cache_warning": "Algo fue mal durante la actualización de la caché de APT (gestor de paquetes de Debian). Aquí tiene un volcado de las líneas de sources.list que podría ayudarle a identificar las líneas problemáticas:\n{sourceslist}",
|
||||||
"update_apt_cache_failed": "No se pudo actualizar la caché de APT (gestor de paquetes de Debian). Aquí tiene un volcado de las líneas de sources.list que podría ayudarle a identificar las líneas problemáticas:\n{sourceslist}",
|
"update_apt_cache_failed": "No se pudo actualizar la caché de APT (gestor de paquetes de Debian). Aquí tiene un volcado de las líneas de sources.list que podría ayudarle a identificar las líneas problemáticas:\n{sourceslist}",
|
||||||
"tools_upgrade_special_packages_completed": "Actualización de paquetes de YunoHost completada.\nPulse [Intro] para regresar a la línea de órdenes",
|
"tools_upgrade_special_packages_completed": "Actualización de paquetes de YunoHost completada.\nPulse [Intro] para regresar a la línea de órdenes",
|
||||||
"tools_upgrade_special_packages_explanation": "Esta acción terminará pero la actualización especial real continuará en segundo plano. No inicie ninguna otra acción en su servidor en aproximadamente 10 minutos (dependiendo de la velocidad de su hardware). Una vez que esté hecho, podría tener que volver a iniciar sesión en la administración web. El registro de actualización estará disponible en Herramientas → Registro (en la página de administración web) o mediante «yunohost log list» (desde la línea de órdenes).",
|
"tools_upgrade_special_packages_explanation": "Esta acción terminará pero la actualización especial real continuará en segundo plano. No inicie ninguna otra acción en su servidor en aproximadamente 10 minutos (dependiendo de la velocidad de su hardware). Una vez hecho, podría tener que volver a iniciar sesión en la administración web. El registro de actualización estará disponible en Herramientas → Registro (en la página de administración web) o mediante «yunohost log list» (desde la línea de órdenes).",
|
||||||
"tools_upgrade_special_packages": "Actualizando ahora paquetes «especiales» (relacionados con YunoHost)…",
|
"tools_upgrade_special_packages": "Actualizando ahora paquetes «especiales» (relacionados con YunoHost)…",
|
||||||
"tools_upgrade_regular_packages_failed": "No se pudieron actualizar los paquetes: {packages_list}",
|
"tools_upgrade_regular_packages_failed": "No se pudieron actualizar los paquetes: {packages_list}",
|
||||||
"tools_upgrade_regular_packages": "Actualizando ahora paquetes «normales» (no relacionados con YunoHost)…",
|
"tools_upgrade_regular_packages": "Actualizando ahora paquetes «normales» (no relacionados con YunoHost)…",
|
||||||
"tools_upgrade_cant_unhold_critical_packages": "No se pudieron liberar los paquetes críticos…",
|
"tools_upgrade_cant_unhold_critical_packages": "No se pudo liberar los paquetes críticos…",
|
||||||
"tools_upgrade_cant_hold_critical_packages": "No se pudieron retener los paquetes críticos…",
|
"tools_upgrade_cant_hold_critical_packages": "No se pudieron retener los paquetes críticos…",
|
||||||
"tools_upgrade_cant_both": "No se puede actualizar el sistema y las aplicaciones al mismo tiempo",
|
"tools_upgrade_cant_both": "No se puede actualizar el sistema y las aplicaciones al mismo tiempo",
|
||||||
"tools_upgrade_at_least_one": "Especifique «--apps», o «--system»",
|
"tools_upgrade_at_least_one": "Especifique «--apps», o «--system»",
|
||||||
"tools_update_failed_to_app_fetchlist": "No se pudo actualizar la lista de aplicaciones de YunoHost porque: {error}",
|
|
||||||
"this_action_broke_dpkg": "Esta acción rompió dpkg/APT(los gestores de paquetes del sistema)… Puede tratar de solucionar este problema conectando mediante SSH y ejecutando `sudo dpkg --configure -a`.",
|
"this_action_broke_dpkg": "Esta acción rompió dpkg/APT(los gestores de paquetes del sistema)… Puede tratar de solucionar este problema conectando mediante SSH y ejecutando `sudo dpkg --configure -a`.",
|
||||||
"system_groupname_exists": "El nombre de grupo ya existe en el grupo del sistema",
|
"service_reloaded_or_restarted": "El servicio «{service:s}» ha sido recargado o reiniciado",
|
||||||
"service_reloaded_or_restarted": "Recargado o reiniciado el servicio «{service:s}»",
|
|
||||||
"service_reload_or_restart_failed": "No se pudo recargar o reiniciar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
"service_reload_or_restart_failed": "No se pudo recargar o reiniciar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
||||||
"service_restarted": "Reiniciado el servicio «{service:s}»",
|
"service_restarted": "Reiniciado el servicio «{service:s}»",
|
||||||
"service_restart_failed": "No se pudo reiniciar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
"service_restart_failed": "No se pudo reiniciar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
||||||
"service_reloaded": "Recargado el servicio «{service:s}»",
|
"service_reloaded": "El servicio «{service:s}» ha sido recargado",
|
||||||
"service_reload_failed": "No se pudo recargar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
"service_reload_failed": "No se pudo recargar el servicio «{service:s}»\n\nRegistro de servicios recientes:{logs:s}",
|
||||||
"service_regen_conf_is_deprecated": "¡«yunohost service regen-conf» está obsoleto! Use «yunohost tools regen-conf» en su lugar.",
|
"service_regen_conf_is_deprecated": "¡«yunohost service regen-conf» está obsoleto! Use «yunohost tools regen-conf» en su lugar.",
|
||||||
"service_description_yunohost-firewall": "Gestiona los puertos de conexiones abiertos y cerrados a los servicios",
|
"service_description_yunohost-firewall": "Gestiona los puertos de conexiones abiertos y cerrados a los servicios",
|
||||||
|
@ -354,15 +253,13 @@
|
||||||
"service_description_ssh": "Permite conectar a su servidor remotamente mediante un terminal (protocolo SSH)",
|
"service_description_ssh": "Permite conectar a su servidor remotamente mediante un terminal (protocolo SSH)",
|
||||||
"service_description_slapd": "Almacena usuarios, dominios e información relacionada",
|
"service_description_slapd": "Almacena usuarios, dominios e información relacionada",
|
||||||
"service_description_rspamd": "Filtra correo no deseado y otras características relacionadas con el correo",
|
"service_description_rspamd": "Filtra correo no deseado y otras características relacionadas con el correo",
|
||||||
"service_description_rmilter": "Comprueba varios parámetros en el correo",
|
|
||||||
"service_description_redis-server": "Una base de datos especializada usada para el acceso rápido de datos, cola de tareas y comunicación entre programas",
|
"service_description_redis-server": "Una base de datos especializada usada para el acceso rápido de datos, cola de tareas y comunicación entre programas",
|
||||||
"service_description_postfix": "Usado para enviar y recibir correos",
|
"service_description_postfix": "Usado para enviar y recibir correos",
|
||||||
"service_description_php7.0-fpm": "Ejecuta aplicaciones escritas en PHP con NGINX",
|
"service_description_php7.0-fpm": "Ejecuta aplicaciones escritas en PHP con NGINX",
|
||||||
"service_description_nslcd": "Maneja la conexión del intérprete de órdenes («shell») de usuario de YunoHost",
|
"service_description_nslcd": "Maneja la conexión del intérprete de órdenes («shell») de usuario de YunoHost",
|
||||||
"service_description_nginx": "Sirve o proporciona acceso a todos los sitios web alojados en su servidor",
|
"service_description_nginx": "Sirve o proporciona acceso a todos los sitios web alojados en su servidor",
|
||||||
"service_description_mysql": "Almacena los datos de las aplicaciones (base de datos SQL)",
|
"service_description_mysql": "Almacena los datos de la aplicación (base de datos SQL)",
|
||||||
"service_description_metronome": "Gestionar las cuentas XMPP de mensajería instantánea",
|
"service_description_metronome": "Gestionar las cuentas XMPP de mensajería instantánea",
|
||||||
"service_description_glances": "Supervisa la información del sistema en su servidor",
|
|
||||||
"service_description_fail2ban": "Protege contra ataques de fuerza bruta y otras clases de ataques desde Internet",
|
"service_description_fail2ban": "Protege contra ataques de fuerza bruta y otras clases de ataques desde Internet",
|
||||||
"service_description_dovecot": "Permite a los clientes de correo acceder/obtener correo (vía IMAP y POP3)",
|
"service_description_dovecot": "Permite a los clientes de correo acceder/obtener correo (vía IMAP y POP3)",
|
||||||
"service_description_dnsmasq": "Maneja la resolución de nombres de dominio (DNS)",
|
"service_description_dnsmasq": "Maneja la resolución de nombres de dominio (DNS)",
|
||||||
|
@ -377,13 +274,13 @@
|
||||||
"restore_removing_tmp_dir_failed": "No se pudo eliminar un directorio temporal antiguo",
|
"restore_removing_tmp_dir_failed": "No se pudo eliminar un directorio temporal antiguo",
|
||||||
"restore_not_enough_disk_space": "Espacio insuficiente (espacio: {free_space:d} B, espacio necesario: {needed_space:d} B, margen de seguridad: {margin:d} B)",
|
"restore_not_enough_disk_space": "Espacio insuficiente (espacio: {free_space:d} B, espacio necesario: {needed_space:d} B, margen de seguridad: {margin:d} B)",
|
||||||
"restore_mounting_archive": "Montando archivo en «{path:s}»",
|
"restore_mounting_archive": "Montando archivo en «{path:s}»",
|
||||||
"restore_may_be_not_enough_disk_space": "Parece que su sistema no tiene suficiente espacio (libre: {free_space:d} B, espacio necesario: {needed_space:d} B, margen de seguridad: {margin:d} B)",
|
"restore_may_be_not_enough_disk_space": "Parece que su sistema no tiene suficiente espacio libre (libre: {free_space:d} B, espacio necesario: {needed_space:d} B, margen de seguridad: {margin:d} B)",
|
||||||
"restore_extracting": "Extrayendo los archivos necesarios para el archivo…",
|
"restore_extracting": "Extrayendo los archivos necesarios para el archivo…",
|
||||||
"regenconf_pending_applying": "Aplicando la configuración pendiente para la categoría «{category}»…",
|
"regenconf_pending_applying": "Aplicando la configuración pendiente para la categoría «{category}»…",
|
||||||
"regenconf_failed": "No se pudo regenerar la configuración para la(s) categoría(s): {categories}",
|
"regenconf_failed": "No se pudo regenerar la configuración para la(s) categoría(s): {categories}",
|
||||||
"regenconf_dry_pending_applying": "Comprobando la configuración pendiente que habría sido aplicada para la categoría «{category}»…",
|
"regenconf_dry_pending_applying": "Comprobando la configuración pendiente que habría sido aplicada para la categoría «{category}»…",
|
||||||
"regenconf_would_be_updated": "La configuración habría sido actualizada para la categoría «{category}»",
|
"regenconf_would_be_updated": "La configuración habría sido actualizada para la categoría «{category}»",
|
||||||
"regenconf_updated": "Actualizada la configuración para la categoría «{category}»",
|
"regenconf_updated": "Actualizada la configuración para la categoría '{category}'",
|
||||||
"regenconf_up_to_date": "Ya está actualizada la configuración para la categoría «{category}»",
|
"regenconf_up_to_date": "Ya está actualizada la configuración para la categoría «{category}»",
|
||||||
"regenconf_now_managed_by_yunohost": "El archivo de configuración «{conf}» está gestionado ahora por YunoHost (categoría {category}).",
|
"regenconf_now_managed_by_yunohost": "El archivo de configuración «{conf}» está gestionado ahora por YunoHost (categoría {category}).",
|
||||||
"regenconf_file_updated": "Actualizado el archivo de configuración «{conf}»",
|
"regenconf_file_updated": "Actualizado el archivo de configuración «{conf}»",
|
||||||
|
@ -394,30 +291,25 @@
|
||||||
"regenconf_file_kept_back": "Se espera que el archivo de configuración «{conf}» sea eliminado por regen-conf (categoría {category}) pero ha sido retenido.",
|
"regenconf_file_kept_back": "Se espera que el archivo de configuración «{conf}» sea eliminado por regen-conf (categoría {category}) pero ha sido retenido.",
|
||||||
"regenconf_file_copy_failed": "No se pudo copiar el nuevo archivo de configuración «{new}» a «{conf}»",
|
"regenconf_file_copy_failed": "No se pudo copiar el nuevo archivo de configuración «{new}» a «{conf}»",
|
||||||
"regenconf_file_backed_up": "Archivo de configuración «{conf}» respaldado en «{backup}»",
|
"regenconf_file_backed_up": "Archivo de configuración «{conf}» respaldado en «{backup}»",
|
||||||
"remove_user_of_group_not_allowed": "No tiene permiso para eliminar al usuario «{user:s}» en el grupo «{group:s}»",
|
|
||||||
"remove_main_permission_not_allowed": "No se permite eliminar el permiso principal",
|
|
||||||
"recommend_to_add_first_user": "La posinstalación ha terminado pero YunoHost necesita al menos un usuario para funcionar correctamente, debe añadir uno ejecutando «yunohost user create <nombredeusuario>» o usando la interfaz de administración.",
|
|
||||||
"permission_update_nothing_to_do": "No hay permisos para actualizar",
|
"permission_update_nothing_to_do": "No hay permisos para actualizar",
|
||||||
"permission_updated": "Actualizado el permiso «{permission:s}» para la aplicación «{app:s}»",
|
"permission_updated": "Actualizado el permiso «{permission:s}»",
|
||||||
"permission_generated": "Actualizada la base de datos de permisos",
|
"permission_generated": "Actualizada la base de datos de permisos",
|
||||||
"permission_update_failed": "No se pudo actualizar el permiso",
|
"permission_update_failed": "No se pudo actualizar el permiso '{permission}': {error}",
|
||||||
"permission_name_not_valid": "Elija un nombre de permiso permitido para «{permission:s}",
|
"permission_name_not_valid": "Elija un nombre de permiso permitido para «{permission:s}",
|
||||||
"permission_not_found": "No se encontró el permiso «{permission:s}» para la aplicación «{app:s}»",
|
"permission_not_found": "No se encontró el permiso «{permission:s}»",
|
||||||
"permission_deletion_failed": "Falta el permiso «{permission:s}» para eliminar la aplicación «{app:s}»",
|
"permission_deletion_failed": "No se pudo eliminar el permiso «{permission}»: {error}",
|
||||||
"permission_deleted": "Eliminado el permiso «{permission:s}» para la aplicación {app:s}",
|
"permission_deleted": "Eliminado el permiso «{permission:s}»",
|
||||||
"permission_creation_failed": "No se pudo conceder el permiso",
|
"permission_creation_failed": "No se pudo crear el permiso «{permission}»: {error}",
|
||||||
"permission_created": "Creado el permiso «{permission:s}» para la aplicación {app:s}",
|
"permission_created": "Creado el permiso «{permission:s}»",
|
||||||
"permission_already_exist": "El permiso «{permission:s}» para la aplicación {app:s} ya existe",
|
"permission_already_exist": "El permiso «{permission}» ya existe",
|
||||||
"permission_already_clear": "El permiso «{permission:s}» ya está definido para la aplicación {app:s}",
|
|
||||||
"pattern_password_app": "Las contraseñas no pueden incluir los siguientes caracteres: {forbidden_chars}",
|
"pattern_password_app": "Las contraseñas no pueden incluir los siguientes caracteres: {forbidden_chars}",
|
||||||
"need_define_permission_before": "Redefina los permisos ejecutando «yunohost user permission add -u USUARIO» antes de eliminar un grupo permitido",
|
|
||||||
"migrations_to_be_ran_manually": "La migración {id} hay que ejecutarla manualmente. Vaya a Herramientas → Migraciones en la página web de administración o ejecute `yunohost tools migrations migrate`.",
|
"migrations_to_be_ran_manually": "La migración {id} hay que ejecutarla manualmente. Vaya a Herramientas → Migraciones en la página web de administración o ejecute `yunohost tools migrations migrate`.",
|
||||||
"migrations_success_forward": "Migración {id} completada",
|
"migrations_success_forward": "Migración {id} completada",
|
||||||
"migrations_skip_migration": "Omitiendo migración {id}…",
|
"migrations_skip_migration": "Omitiendo migración {id}…",
|
||||||
"migrations_running_forward": "Ejecutando migración {id}…",
|
"migrations_running_forward": "Ejecutando migración {id}…",
|
||||||
"migrations_pending_cant_rerun": "Esas migraciones están aún pendientes, así que no se pueden volver a ejecutar: {ids}",
|
"migrations_pending_cant_rerun": "Esas migraciones están aún pendientes, así que no se pueden volver a ejecutar: {ids}",
|
||||||
"migrations_not_pending_cant_skip": "Esas migraciones no están pendientes, así que no pueden ser omitidas: {ids}",
|
"migrations_not_pending_cant_skip": "Esas migraciones no están pendientes, así que no pueden ser omitidas: {ids}",
|
||||||
"migrations_no_such_migration": "No hay ninguna migración llamada {id}",
|
"migrations_no_such_migration": "No hay ninguna migración llamada «{id}»",
|
||||||
"migrations_no_migrations_to_run": "No hay migraciones que ejecutar",
|
"migrations_no_migrations_to_run": "No hay migraciones que ejecutar",
|
||||||
"migrations_need_to_accept_disclaimer": "Para ejecutar la migración {id} debe aceptar el siguiente descargo de responsabilidad:\n---\n{disclaimer}\n---\nSi acepta ejecutar la migración, vuelva a ejecutar la orden con la opción «--accept-disclaimer».",
|
"migrations_need_to_accept_disclaimer": "Para ejecutar la migración {id} debe aceptar el siguiente descargo de responsabilidad:\n---\n{disclaimer}\n---\nSi acepta ejecutar la migración, vuelva a ejecutar la orden con la opción «--accept-disclaimer».",
|
||||||
"migrations_must_provide_explicit_targets": "Necesita proporcionar objetivos explícitos al usar «--skip» or «--force-rerun»",
|
"migrations_must_provide_explicit_targets": "Necesita proporcionar objetivos explícitos al usar «--skip» or «--force-rerun»",
|
||||||
|
@ -426,47 +318,46 @@
|
||||||
"migrations_list_conflict_pending_done": "No puede usar «--previous» y «--done» al mismo tiempo.",
|
"migrations_list_conflict_pending_done": "No puede usar «--previous» y «--done» al mismo tiempo.",
|
||||||
"migrations_exclusive_options": "«--auto», «--skip», and «--force-rerun» son opciones mutuamente excluyentes.",
|
"migrations_exclusive_options": "«--auto», «--skip», and «--force-rerun» son opciones mutuamente excluyentes.",
|
||||||
"migrations_failed_to_load_migration": "No se pudo cargar la migración {id}: {error}",
|
"migrations_failed_to_load_migration": "No se pudo cargar la migración {id}: {error}",
|
||||||
"migrations_dependencies_not_satisfied": "No se puede ejecutar la migración {id} porque primero necesita ejecutar estas migraciones: {dependencies_id}",
|
"migrations_dependencies_not_satisfied": "Ejecutar estas migraciones: «{dependencies_id}» antes de migrar {id}.",
|
||||||
"migrations_cant_reach_migration_file": "No se pudo acceder los archivos de migración en la ruta %s",
|
"migrations_cant_reach_migration_file": "No se pudo acceder a los archivos de migración en la ruta «%s»",
|
||||||
"migrations_already_ran": "Esas migraciones ya se han realizado: {ids}",
|
"migrations_already_ran": "Esas migraciones ya se han realizado: {ids}",
|
||||||
"migration_0011_update_LDAP_schema": "Actualizando el esquema de LDAP…",
|
"migration_0011_update_LDAP_schema": "Actualizando el esquema de LDAP…",
|
||||||
"migration_0011_update_LDAP_database": "Actualizando la base de datos de LDAP…",
|
"migration_0011_update_LDAP_database": "Actualizando la base de datos de LDAP…",
|
||||||
"migration_0011_rollback_success": "Sistema revertido.",
|
"migration_0011_rollback_success": "Sistema revertido.",
|
||||||
"migration_0011_migration_failed_trying_to_rollback": "Migración fallida… intentando revertir el sistema.",
|
"migration_0011_migration_failed_trying_to_rollback": "No se pudo migrar… intentando revertir el sistema.",
|
||||||
"migration_0011_migrate_permission": "Migrando permisos desde la configuración de las aplicaciones a LDAP…",
|
"migration_0011_migrate_permission": "Migrando permisos desde la configuración de las aplicaciones a LDAP…",
|
||||||
"migration_0011_LDAP_update_failed": "No se pudo actualizar LDAP. Error: {error:s}",
|
"migration_0011_LDAP_update_failed": "No se pudo actualizar LDAP. Error: {error:s}",
|
||||||
"migration_0011_LDAP_config_dirty": "Parece que ha personalizado la configuración de LDAP. Para esta migración se necesita actualizar la configuración de LDAP.\nNecesita guardar su configuración actual, reiniciar la configuración original ejecutando «yunohost tools regen-conf -f» y reintentar la migración",
|
"migration_0011_done": "Migración finalizada. Ahora puede gestionar los grupos de usuarios.",
|
||||||
"migration_0011_done": "Migración correcta. Ahora puede gestionar los grupos de usuarios.",
|
|
||||||
"migration_0011_create_group": "Creando un grupo para cada usuario…",
|
"migration_0011_create_group": "Creando un grupo para cada usuario…",
|
||||||
"migration_0011_can_not_backup_before_migration": "No se pudo respaldar el sistema antes de la migración. Error: {error:s}",
|
"migration_0011_can_not_backup_before_migration": "El respaldo del sistema no se pudo completar antes de que la migración fallase. Error: {error:s}",
|
||||||
"migration_0011_backup_before_migration": "Creando un respaldo de la base de datos de LDAP y de la configuración de las aplicaciones antes de la migración real.",
|
"migration_0011_backup_before_migration": "Creando un respaldo de la base de datos de LDAP y de la configuración de las aplicaciones antes de la migración real.",
|
||||||
"migration_0009_not_needed": "La migración ya ocurrió de algún modo… (?) Omitiendo.",
|
"migration_0009_not_needed": "La migración ya ocurrió de algún modo… (?) Omitiendo.",
|
||||||
"migration_0008_no_warning": "No se ha detectado ningún riesgo importante con respecto a la anulación de su configuración SSH ¡sin embargo uno nunca puede estar absolutamente seguro ;)! Ejecute la migración para anularla. Por otra parte, puede omitir la migración aunque no esté recomendado.",
|
"migration_0008_no_warning": "Sobre escribir su configuración SSH debería ser seguro ¡aunque esto no se puede prometer! Ejecute la migración para ignorarla. Por otra parte puede omitir la migración, aunque no se recomienda.",
|
||||||
"migration_0008_warning": "Si entiende esos avisos y permite a YunoHost anular su configuración actual, ejecute la migración. Por otra parte puede omitir la migración, aunque no se recomienda.",
|
"migration_0008_warning": "Si entiende esos avisos y quiere que YunoHost ignore su configuración actual, ejecute la migración. Por otra parte puede omitir la migración, aunque no se recomienda.",
|
||||||
"migration_0008_dsa": "• Se desactivará la clave DSA. Así que podría tener que anular un aviso espeluznante de su cliente SSH y volver a comprobar la huella de su servidor;",
|
"migration_0008_dsa": "• Se desactivará la clave DSA. Así que podría tener que anular un aviso espeluznante de su cliente SSH y volver a comprobar la huella de su servidor;",
|
||||||
"migration_0008_root": "• No podrá conectarse como «root» a través de SSH. En su lugar debe usar el usuario «admin»;",
|
"migration_0008_root": "• No podrá conectarse como «root» a través de SSH. En su lugar debe usar el usuario «admin»;",
|
||||||
"migration_0008_port": "• Tendrá que conectarse usando el puerto 22 en vez de su actual puerto SSH personalizado. No dude en reconfigurarlo;",
|
"migration_0008_port": "• Tendrá que conectarse usando el puerto 22 en vez de su actual puerto SSH personalizado. No dude en reconfigurarlo;",
|
||||||
"migration_0008_general_disclaimer": "Para mejorar la seguridad de su servidor, es recomendable permitir a YunoHost gestionar la configuración de SSH. Su actual configuración de SSH difiere de la recomendación. Si permite a YunoHost reconfigurarla, la manera en la que conecta con su servidor a través de SSH cambiará así:",
|
"migration_0008_general_disclaimer": "Para mejorar la seguridad de su servidor, es recomendable permitir a YunoHost gestionar la configuración de SSH. Su actual configuración de SSH difiere de la recomendación. Si permite a YunoHost reconfigurarla, la manera en la que conecta con su servidor a través de SSH cambiará así:",
|
||||||
"migration_0007_cannot_restart": "No se puede reiniciar SSH después de intentar cancelar la migración número 6.",
|
"migration_0007_cannot_restart": "No se puede reiniciar SSH después de intentar cancelar la migración número 6.",
|
||||||
"migration_0007_cancelled": "YunoHost no ha podido mejorar el modo en el que se gestiona su configuración de SSH.",
|
"migration_0007_cancelled": "No se pudo mejorar el modo en el que se gestiona su configuración de SSH.",
|
||||||
"migration_0006_disclaimer": "YunoHost espera ahora que las contraseñas de «admin» y «root» estén sincronizadas. Al ejecutar esta migración, su contraseña de «root» será reemplazada por la contraseña de administración.",
|
"migration_0006_disclaimer": "YunoHost espera ahora que las contraseñas de «admin» y «root» estén sincronizadas. Esta migración reemplaza su contraseña de «root» por la contraseña de «admin».",
|
||||||
"migration_0005_not_enough_space": "Tenga suficiente espacio libre disponible en {path} para ejecutar la migración.",
|
"migration_0005_not_enough_space": "Tenga suficiente espacio libre disponible en {path} para ejecutar la migración.",
|
||||||
"migration_0005_postgresql_96_not_installed": "⸘PostgreSQL 9.4 está instalado pero no PostgreSQL 9.6‽ Algo raro podría haber ocurrido en su sistema:(…",
|
"migration_0005_postgresql_96_not_installed": "PostgreSQL 9.4 está instalado pero no PostgreSQL 9.6. Algo raro podría haber ocurrido en su sistema:(…",
|
||||||
"migration_0005_postgresql_94_not_installed": "PostgreSQL no estaba instalado en su sistema. Nada que hacer.",
|
"migration_0005_postgresql_94_not_installed": "PostgreSQL no estaba instalado en su sistema. Nada que hacer.",
|
||||||
"migration_0003_modified_files": "Tenga en cuenta que se encontró que los siguientes archivos fueron modificados manualmente y podrían ser sobrescritos después de la actualización: {manually_modified_files}",
|
"migration_0003_modified_files": "Tenga en cuenta que se encontró que los siguientes archivos fueron modificados manualmente y podrían ser sobrescritos después de la actualización: {manually_modified_files}",
|
||||||
"migration_0003_problematic_apps_warning": "Tenga en cuenta que se detectaron las siguientes aplicaciones instaladas posiblemente problemáticas. Parece que no fueron instaladas desde una lista de aplicaciones o no estaban etiquetadas como «funciona». Así que no hay garantía de que aún funcionen después de la actualización: {problematic_apps}",
|
"migration_0003_problematic_apps_warning": "Tenga en cuenta que las aplicaciones listadas mas abajo fueron detectadas como 'posiblemente problemáticas'. Parece que no fueron instaladas desde una lista de aplicaciones o no estaban etiquetadas como 'funcional'. Así que no hay garantía de que aún funcionen después de la actualización: {problematic_apps}",
|
||||||
"migration_0003_general_warning": "Tenga en cuenta que esta migración es una operación delicada. El equipo de YunoHost ha hecho todo lo posible para revisarla y probarla, pero la migración aún podría romper parte del sistema o de sus aplicaciones.\n\nPor lo tanto, se recomienda que:\n - Realice una copia de seguridad de cualquier dato crítico o aplicación. Más información en https://yunohost.org/backup;\n - Tenga paciencia tras iniciar la migración: dependiendo de su conexión a Internet y de su hardware, podría tardar unas cuantas horas hasta que todo se actualice.\n\nAdemás, el puerto para SMTP usado por los clientes de correo externos (como Thunderbird o K9-Mail) cambió de 465 (SSL/TLS) a 587 (STARTTLS). El antiguo puerto (465) se cerrará automáticamente y el nuevo puerto (587) se abrirá en el cortafuegos. Todos los usuarios *tendrán* que adaptar la configuración de sus clientes de correo por lo tanto.",
|
"migration_0003_general_warning": "Tenga en cuenta que esta migración es una operación delicada. El equipo de YunoHost ha hecho todo lo posible para revisarla y probarla, pero la migración aún podría romper parte del sistema o de sus aplicaciones.\n\nPor lo tanto, se recomienda que:\n - Realice una copia de seguridad de cualquier dato crítico o aplicación. Más información en https://yunohost.org/backup;\n - Tenga paciencia tras iniciar la migración: dependiendo de su conexión a Internet y de su hardware, podría tardar unas cuantas horas hasta que todo se actualice.\n\nAdemás, el puerto para SMTP usado por los clientes de correo externos (como Thunderbird o K9-Mail) cambió de 465 (SSL/TLS) a 587 (STARTTLS). El antiguo puerto (465) se cerrará automáticamente y el nuevo puerto (587) se abrirá en el cortafuegos. Todos los usuarios *tendrán* que adaptar la configuración de sus clientes de correo por lo tanto.",
|
||||||
"migration_0003_still_on_jessie_after_main_upgrade": "Algo fue mal durante la actualización principal: ⸘el sistema está aún en Jessie‽ Para investigar el problema, vea {log}:s…",
|
"migration_0003_still_on_jessie_after_main_upgrade": "Algo fue mal durante la actualización principal: ⸘el sistema está aún en Jessie‽ Para investigar el problema, vea {log}:s…",
|
||||||
"migration_0003_system_not_fully_up_to_date": "Su sistema no está totalmente actualizado. Realice una actualización normal antes de ejecutar la migración a Stretch.",
|
"migration_0003_system_not_fully_up_to_date": "Su sistema no está totalmente actualizado. Realice una actualización normal antes de ejecutar la migración a Stretch.",
|
||||||
"migration_0003_not_jessie": "¡La distribución de Debian actual no es Jessie!",
|
"migration_0003_not_jessie": "¡La distribución de Debian actual no es Jessie!",
|
||||||
"migration_0003_yunohost_upgrade": "Iniciando la actualización del paquete YunoHost… La migración finalizará pero la actualización real ocurrirá inmediatamente después. Después de que la operación esté completada, podría tener que iniciar sesión en la página de administración de nuevo.",
|
"migration_0003_yunohost_upgrade": "Iniciando la actualización del paquete YunoHost… la actualización ocurrirá inmediatamente después de que la migración finalizará. Después de que la operación esté completada, podría tener que iniciar sesión en la página de administración de nuevo.",
|
||||||
"migration_0003_restoring_origin_nginx_conf": "Su archivo /etc/nginx/nginx.conf ha sido editado de algún modo. La migración lo devolverá a su estado original primero… El archivo anterior estará disponible como {backup_dest}.",
|
"migration_0003_restoring_origin_nginx_conf": "Su archivo /etc/nginx/nginx.conf ha sido editado. La migración lo devolverá a su estado original… El archivo anterior estará disponible como {backup_dest}.",
|
||||||
"migration_0003_fail2ban_upgrade": "Iniciando la actualización de Fail2Ban…",
|
"migration_0003_fail2ban_upgrade": "Iniciando la actualización de Fail2Ban…",
|
||||||
"migration_0003_main_upgrade": "Iniciando la actualización principal…",
|
"migration_0003_main_upgrade": "Iniciando la actualización principal…",
|
||||||
"migration_0003_patching_sources_list": "Corrigiendo «sources.lists»…",
|
"migration_0003_patching_sources_list": "Corrigiendo «sources.lists»…",
|
||||||
"migration_0003_start": "Iniciando migración a Stretch. El registro estará disponible en {logfile}.",
|
"migration_0003_start": "Iniciando migración a Stretch. El registro estará disponible en {logfile}.",
|
||||||
"migration_description_0012_postgresql_password_to_md5_authentication": "Forzar a la autentificación de PostgreSQL a usar MD5 para las conexiones locales",
|
"migration_description_0012_postgresql_password_to_md5_authentication": "Forzar a la autentificación de PostgreSQL a usar MD5 para las conexiones locales",
|
||||||
"migration_description_0011_setup_group_permission": "Configurar grupo de usuario y configurar permisos para aplicaciones y servicios",
|
"migration_description_0011_setup_group_permission": "Configurar grupo de usuario y permisos para aplicaciones y servicios",
|
||||||
"migration_description_0010_migrate_to_apps_json": "Eliminar las listas de aplicaciones («appslists») obsoletas y usar en su lugar la nueva lista unificada «apps.json»",
|
"migration_description_0010_migrate_to_apps_json": "Eliminar las listas de aplicaciones («appslists») obsoletas y usar en su lugar la nueva lista unificada «apps.json»",
|
||||||
"migration_description_0009_decouple_regenconf_from_services": "Separar el mecanismo «regen-conf» de los servicios",
|
"migration_description_0009_decouple_regenconf_from_services": "Separar el mecanismo «regen-conf» de los servicios",
|
||||||
"migration_description_0008_ssh_conf_managed_by_yunohost_step2": "Permitir que la configuración de SSH la gestione YunoHost (paso 2, manual)",
|
"migration_description_0008_ssh_conf_managed_by_yunohost_step2": "Permitir que la configuración de SSH la gestione YunoHost (paso 2, manual)",
|
||||||
|
@ -491,23 +382,16 @@
|
||||||
"log_tools_shutdown": "Apagar el servidor",
|
"log_tools_shutdown": "Apagar el servidor",
|
||||||
"log_tools_upgrade": "Actualizar paquetes del sistema",
|
"log_tools_upgrade": "Actualizar paquetes del sistema",
|
||||||
"log_tools_postinstall": "Posinstalación del servidor YunoHost",
|
"log_tools_postinstall": "Posinstalación del servidor YunoHost",
|
||||||
"log_tools_migrations_migrate_forward": "Migrar hacia adelante",
|
"log_tools_migrations_migrate_forward": "Inicializa la migración",
|
||||||
"log_tools_maindomain": "Convertir «{}» en el dominio principal",
|
|
||||||
"log_user_permission_remove": "Actualizar permiso «{}»",
|
|
||||||
"log_user_permission_add": "Actualizar permiso «{}»",
|
|
||||||
"log_user_update": "Actualizar la información de usuario de «{}»",
|
"log_user_update": "Actualizar la información de usuario de «{}»",
|
||||||
"log_user_group_update": "Actualizar grupo «{}»",
|
"log_user_group_update": "Actualizar grupo «{}»",
|
||||||
"log_user_group_delete": "Eliminar grupo «{}»",
|
"log_user_group_delete": "Eliminar grupo «{}»",
|
||||||
"log_user_group_add": "Añadir grupo «{}»",
|
|
||||||
"log_user_delete": "Eliminar usuario «{}»",
|
"log_user_delete": "Eliminar usuario «{}»",
|
||||||
"log_user_create": "Añadir usuario «{}»",
|
"log_user_create": "Añadir usuario «{}»",
|
||||||
"log_regen_conf": "Regenerar la configuración del sistema «{}»",
|
"log_regen_conf": "Regenerar la configuración del sistema «{}»",
|
||||||
"log_letsencrypt_cert_renew": "Renovar el certificado «{}» de Let's encrypt",
|
"log_letsencrypt_cert_renew": "Renovar el certificado «{}» de Let's Encrypt",
|
||||||
"log_selfsigned_cert_install": "Instalar certificado autofirmado en el dominio «{}»",
|
"log_selfsigned_cert_install": "Instalar el certificado auto-firmado en el dominio '{}'",
|
||||||
"log_permission_update": "Actualizar permiso «{}» para la aplicación «{}»",
|
"log_letsencrypt_cert_install": "Instalar un certificado de Let's Encrypt en el dominio «{}»",
|
||||||
"log_permission_remove": "Eliminar permiso «{}»",
|
|
||||||
"log_permission_add": "Añadir el permiso «{}» para la aplicación «{}»",
|
|
||||||
"log_letsencrypt_cert_install": "Instalar un certificado de Let's encrypt en el dominio «{}»",
|
|
||||||
"log_dyndns_update": "Actualizar la IP asociada con su subdominio de YunoHost «{}»",
|
"log_dyndns_update": "Actualizar la IP asociada con su subdominio de YunoHost «{}»",
|
||||||
"log_dyndns_subscribe": "Subscribirse a un subdomino de YunoHost «{}»",
|
"log_dyndns_subscribe": "Subscribirse a un subdomino de YunoHost «{}»",
|
||||||
"log_domain_remove": "Eliminar el dominio «{}» de la configuración del sistema",
|
"log_domain_remove": "Eliminar el dominio «{}» de la configuración del sistema",
|
||||||
|
@ -522,13 +406,8 @@
|
||||||
"log_app_remove": "Eliminar la aplicación «{}»",
|
"log_app_remove": "Eliminar la aplicación «{}»",
|
||||||
"log_app_install": "Instalar la aplicación «{}»",
|
"log_app_install": "Instalar la aplicación «{}»",
|
||||||
"log_app_change_url": "Cambiar el URL de la aplicación «{}»",
|
"log_app_change_url": "Cambiar el URL de la aplicación «{}»",
|
||||||
"log_app_removelist": "Eliminar una lista de aplicaciones",
|
|
||||||
"log_app_fetchlist": "Añadir una lista de aplicaciones",
|
|
||||||
"log_app_clearaccess": "Eliminar todos los accesos a «{}»",
|
|
||||||
"log_app_removeaccess": "Eliminar acceso a «{}»",
|
|
||||||
"log_app_addaccess": "Añadir acceso a «{}»",
|
|
||||||
"log_operation_unit_unclosed_properly": "La unidad de operación no se ha cerrado correctamente",
|
"log_operation_unit_unclosed_properly": "La unidad de operación no se ha cerrado correctamente",
|
||||||
"log_does_exists": "No existe ningún registro de actividades con el nombre «{log}», ejecute «yunohost log list» para ver todos los registros de actividades disponibles",
|
"log_does_exists": "No existe ningún registro de actividades con el nombre '{log}', ejecute 'yunohost log list' para ver todos los registros de actividades disponibles",
|
||||||
"log_help_to_get_failed_log": "No se pudo completar la operación «{desc}». Para obtener ayuda, comparta el registro completo de esta operación ejecutando la orden «yunohost log display {name} --share»",
|
"log_help_to_get_failed_log": "No se pudo completar la operación «{desc}». Para obtener ayuda, comparta el registro completo de esta operación ejecutando la orden «yunohost log display {name} --share»",
|
||||||
"log_link_to_failed_log": "No se pudo completar la operación «{desc}». Para obtener ayuda, proporcione el registro completo de esta operación <a href=\"#/tools/logs/{name}\">pulsando aquí</a>",
|
"log_link_to_failed_log": "No se pudo completar la operación «{desc}». Para obtener ayuda, proporcione el registro completo de esta operación <a href=\"#/tools/logs/{name}\">pulsando aquí</a>",
|
||||||
"log_help_to_get_log": "Para ver el registro de la operación «{desc}», ejecute la orden «yunohost log display {name}»",
|
"log_help_to_get_log": "Para ver el registro de la operación «{desc}», ejecute la orden «yunohost log display {name}»",
|
||||||
|
@ -536,18 +415,13 @@
|
||||||
"log_category_404": "La categoría de registro «{category}» no existe",
|
"log_category_404": "La categoría de registro «{category}» no existe",
|
||||||
"log_corrupted_md_file": "El archivo de metadatos YAML asociado con el registro está dañado: «{md_file}\nError: {error}»",
|
"log_corrupted_md_file": "El archivo de metadatos YAML asociado con el registro está dañado: «{md_file}\nError: {error}»",
|
||||||
"hook_json_return_error": "No se pudo leer la respuesta del gancho {path:s}. Error: {msg:s}. Contenido sin procesar: {raw_content}",
|
"hook_json_return_error": "No se pudo leer la respuesta del gancho {path:s}. Error: {msg:s}. Contenido sin procesar: {raw_content}",
|
||||||
"group_update_failed": "No se pudo actualizar el grupo «{group}»",
|
"group_update_failed": "No se pudo actualizar el grupo «{group}»: {error}",
|
||||||
"group_updated": "Grupo «{group}» actualizado",
|
"group_updated": "Grupo «{group}» actualizado",
|
||||||
"group_unknown": "El grupo «{group:s}» es desconocido",
|
"group_unknown": "El grupo «{group:s}» es desconocido",
|
||||||
"group_info_failed": "No se pudo mostrar la información del grupo",
|
"group_deletion_failed": "No se pudo eliminar el grupo «{group}»: {error}",
|
||||||
"group_deletion_not_allowed": "No se puede eliminar el grupo {group:s} manualmente.",
|
|
||||||
"group_deletion_failed": "No se pudo eliminar el grupo «{group}»",
|
|
||||||
"group_deleted": "Eliminado el grupo «{group}»",
|
"group_deleted": "Eliminado el grupo «{group}»",
|
||||||
"group_creation_failed": "No se pudo crear el grupo «{group}»",
|
"group_creation_failed": "No se pudo crear el grupo «{group}»: {error}",
|
||||||
"group_created": "Creado el grupo «{group}»",
|
"group_created": "Creado el grupo «{group}»",
|
||||||
"group_name_already_exist": "El grupo {name:s} ya existe",
|
|
||||||
"group_already_disallowed": "El grupo «{group:s}» ya tiene desactivado el permiso «{permission:s}» para la aplicación «{app:s}»",
|
|
||||||
"group_already_allowed": "El grupo «{group:s}» ya tiene activado el permiso «{permission:s}» para la aplicación «{app:s}»",
|
|
||||||
"good_practices_about_admin_password": "Va a establecer una nueva contraseña de administración. La contraseña debería tener al menos 8 caracteres, aunque es una buena práctica usar una contraseña más extensa (básicamente una frase) y/o usar caracteres de varias clases (mayúsculas, minúsculas, números y caracteres especiales).",
|
"good_practices_about_admin_password": "Va a establecer una nueva contraseña de administración. La contraseña debería tener al menos 8 caracteres, aunque es una buena práctica usar una contraseña más extensa (básicamente una frase) y/o usar caracteres de varias clases (mayúsculas, minúsculas, números y caracteres especiales).",
|
||||||
"global_settings_unknown_type": "Situación imprevista, la configuración {setting:s} parece tener el tipo {unknown_type:s} pero no es un tipo compatible con el sistema.",
|
"global_settings_unknown_type": "Situación imprevista, la configuración {setting:s} parece tener el tipo {unknown_type:s} pero no es un tipo compatible con el sistema.",
|
||||||
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Permitir el uso de la llave (obsoleta) DSA para la configuración del demonio SSH",
|
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Permitir el uso de la llave (obsoleta) DSA para la configuración del demonio SSH",
|
||||||
|
@ -569,20 +443,16 @@
|
||||||
"global_settings_bad_type_for_setting": "Tipo erróneo para la configuración {setting:s}, obtuvo {received_type:s}, esperado {expected_type:s}",
|
"global_settings_bad_type_for_setting": "Tipo erróneo para la configuración {setting:s}, obtuvo {received_type:s}, esperado {expected_type:s}",
|
||||||
"global_settings_bad_choice_for_enum": "Opción errónea para la configuración {setting:s}, obtuvo «{choice:s}» pero las opciones disponibles son: {available_choices:s}",
|
"global_settings_bad_choice_for_enum": "Opción errónea para la configuración {setting:s}, obtuvo «{choice:s}» pero las opciones disponibles son: {available_choices:s}",
|
||||||
"file_does_not_exist": "El archivo {path:s} no existe.",
|
"file_does_not_exist": "El archivo {path:s} no existe.",
|
||||||
"error_when_removing_sftpuser_group": "No se pudo eliminar el grupo sftpusers",
|
|
||||||
"edit_permission_with_group_all_users_not_allowed": "No puede editar el permiso para el grupo «all_users», utilice «yunohost user permission clear APLICACIÓN» o «yunohost user permission add APLICACIÓN -u USUARIO».",
|
|
||||||
"edit_group_not_allowed": "No tiene permiso para editar el grupo {group:s}",
|
|
||||||
"dyndns_could_not_check_available": "No se pudo comprobar si {domain:s} está disponible en {provider:s}.",
|
"dyndns_could_not_check_available": "No se pudo comprobar si {domain:s} está disponible en {provider:s}.",
|
||||||
"domain_dyndns_dynette_is_unreachable": "No se pudo conectar a dynette de YunoHost. O su YunoHost no está correctamente conectado a Internet o el servidor dynette está caído. Error: {error}",
|
|
||||||
"domain_dns_conf_is_just_a_recommendation": "Esta orden muestra la configuración *recomendada*. No configura el DNS en realidad. Es su responsabilidad configurar la zona de DNS en su registrador según esta recomendación.",
|
"domain_dns_conf_is_just_a_recommendation": "Esta orden muestra la configuración *recomendada*. No configura el DNS en realidad. Es su responsabilidad configurar la zona de DNS en su registrador según esta recomendación.",
|
||||||
"dpkg_lock_not_available": "Esta orden no se puede ejecutar en este momento porque otro programa parece que está usando el bloqueo de dpkg (el gestor de paquetes del sistema)",
|
"dpkg_lock_not_available": "Esta orden no se puede ejecutar en este momento ,parece que programa está usando el bloqueo de dpkg (el gestor de paquetes del sistema)",
|
||||||
"dpkg_is_broken": "No puede hacer esto en este momento porque dpkg/apt (los gestores de paquetes del sistema) parecen estar en un estado roto... Puede tratar de solucionar este problema conectando a través de SSH y ejecutando `sudo dpkg --configure -a`.",
|
"dpkg_is_broken": "No puede hacer esto en este momento porque dpkg/apt (los gestores de paquetes del sistema) parecen estar en un estado roto... Puede tratar de solucionar este problema conectando a través de SSH y ejecutando `sudo dpkg --configure -a`.",
|
||||||
"confirm_app_install_thirdparty": "¡AVISO! Instalar aplicaciones de terceros podría comprometer la integridad y seguridad de su sistema. Probablemente NO debería instalarlas salvo que sepa lo que está haciendo. ¿Está dispuesto a correr ese riesgo? [{answers:s}] ",
|
"confirm_app_install_thirdparty": "¡PELIGRO! Esta aplicación no forma parte del catálogo de aplicaciones de YunoHost. Instalar aplicaciones de terceros podría comprometer la integridad y seguridad de su sistema. Probablemente NO debería instalarla salvo que sepa lo que está haciendo. No tendrá NINGUNA AYUDA si esta aplicación no funciona o rompe su sistema… Si está dispuesto a aceptar ese riesgo de todas formas, escriba «{answers:s}»",
|
||||||
"confirm_app_install_danger": "¡AVISO! Esta aplicación es aún experimental (si no está funcionando expresamente) y ¡es probable que rompa su sistema! Probablemente NO debería instalarla salvo que sepa lo que está haciendo. ¿Está dispuesto a correr ese riesgo? [{answers:s}] ",
|
"confirm_app_install_danger": "¡PELIGRO! ¡Esta aplicación es conocida por ser aún experimental (o no funciona explícitamente)! Probablemente NO debería instalarla salvo que sepa lo que está haciendo. No tendrá NINGUNA AYUDA si esta aplicación no funciona o rompe su sistema… Si está dispuesto a aceptar ese riesgo de todas formas, escriba «{answers:s}»",
|
||||||
"confirm_app_install_warning": "Aviso: esta aplicación puede funcionar pero no está bien integrada en YunoHost. Algunas herramientas como la autentificación única y respaldo/restauración podrían no estar disponibles. ¿Instalar de todos modos? [{answers:s}] ",
|
"confirm_app_install_warning": "Aviso: esta aplicación puede funcionar pero no está bien integrada en YunoHost. Algunas herramientas como la autentificación única y respaldo/restauración podrían no estar disponibles. ¿Instalar de todos modos? [{answers:s}] ",
|
||||||
"backup_unable_to_organize_files": "No se pudo usar el método rápido de organización de los archivos en el archivo",
|
"backup_unable_to_organize_files": "No se pudo usar el método rápido de organización de los archivos en el archivo",
|
||||||
"backup_permission": "Permiso de respaldo para la aplicación {app:s}",
|
"backup_permission": "Permiso de respaldo para la aplicación {app:s}",
|
||||||
"backup_output_symlink_dir_broken": "Tiene un enlace simbólico roto en vez del directorio «{path:s}» de su archivo. Puede que tenga una configuración específica para respaldar sus datos en otro sistema de archivos, en este caso probablemente olvidó remontar o conectar su disco duro o clave USB.",
|
"backup_output_symlink_dir_broken": "El directorio de su archivo «{path:s}» es un enlace simbólico roto. Tal vez olvidó (re)montarlo o conectarlo al medio de almacenamiento al que apunta.",
|
||||||
"backup_mount_archive_for_restore": "Preparando el archivo para la restauración…",
|
"backup_mount_archive_for_restore": "Preparando el archivo para la restauración…",
|
||||||
"backup_method_tar_finished": "Creado el archivo TAR de respaldo",
|
"backup_method_tar_finished": "Creado el archivo TAR de respaldo",
|
||||||
"backup_method_custom_finished": "Terminado el método «{method:s}» de respaldo personalizado",
|
"backup_method_custom_finished": "Terminado el método «{method:s}» de respaldo personalizado",
|
||||||
|
@ -592,19 +462,141 @@
|
||||||
"backup_actually_backuping": "Creando un archivo de respaldo de los archivos obtenidos…",
|
"backup_actually_backuping": "Creando un archivo de respaldo de los archivos obtenidos…",
|
||||||
"ask_new_path": "Nueva ruta",
|
"ask_new_path": "Nueva ruta",
|
||||||
"ask_new_domain": "Nuevo dominio",
|
"ask_new_domain": "Nuevo dominio",
|
||||||
"apps_permission_restoration_failed": "Otorgar el permiso «{permission:s}» para restaurar {app:s}",
|
|
||||||
"apps_permission_not_found": "No se han encontrado permisos para las aplicaciones instaladas",
|
|
||||||
"app_upgrade_several_apps": "Las siguientes aplicaciones se actualizarán: {apps}",
|
"app_upgrade_several_apps": "Las siguientes aplicaciones se actualizarán: {apps}",
|
||||||
"app_start_restore": "Restaurando aplicación {app}…",
|
"app_start_restore": "Restaurando aplicación «{app}»…",
|
||||||
"app_start_backup": "Obteniendo archivos para el respaldo de {app}…",
|
"app_start_backup": "Obteniendo archivos para el respaldo de «{app}»…",
|
||||||
"app_start_remove": "Eliminando aplicación {app}…",
|
"app_start_remove": "Eliminando aplicación «{app}»…",
|
||||||
"app_start_install": "Instalando aplicación {app}…",
|
"app_start_install": "Instalando aplicación «{app}»…",
|
||||||
"app_not_upgraded": "Error al actualizar la aplicación «{failed_app}» y como consecuencia se han cancelado las actualizaciones de las siguientes aplicaciones: {apps}",
|
"app_not_upgraded": "Error al actualizar la aplicación «{failed_app}» y como consecuencia se han cancelado las actualizaciones de las siguientes aplicaciones: {apps}",
|
||||||
"app_action_cannot_be_ran_because_required_services_down": "Esta aplicación necesita algunos servicios que no están funcionando ahora. Antes de continuar, debería intentar reiniciar los siguientes servicios (y posiblemente investigar por qué no funcionan): {services}",
|
"app_action_cannot_be_ran_because_required_services_down": "Estos servicios necesarios deberían estar funcionando para ejecutar esta acción: {services}. Pruebe a reiniciarlos para continuar (y posiblemente investigar por qué están caídos).",
|
||||||
"already_up_to_date": "Nada que hacer. Todo está actualizado.",
|
"already_up_to_date": "Nada que hacer. Todo está actualizado.",
|
||||||
"admin_password_too_long": "Elija una contraseña de menos de 127 caracteres",
|
"admin_password_too_long": "Elija una contraseña de menos de 127 caracteres",
|
||||||
"aborting": "Cancelando.",
|
"aborting": "Cancelando.",
|
||||||
"app_upgrade_stopped": "Se ha detenido la actualización de todas las aplicaciones para prevenir un posible daño porque la aplicación anterior no se pudo actualizar",
|
"app_action_broke_system": "Esta acción parece que ha roto estos servicios importantes: {services}",
|
||||||
"app_action_broke_system": "Esta acción parece que ha roto estos importantes servicios: {services}",
|
"operation_interrupted": "¿Ha sido interrumpida la operación manualmente?",
|
||||||
"operation_interrupted": "¿Ha sido interrumpida la operación manualmente?"
|
"apps_already_up_to_date": "Todas las aplicaciones están ya actualizadas",
|
||||||
|
"dyndns_provider_unreachable": "No se puede conectar con el proveedor de Dyndns {provider}: o su YunoHost no está correctamente conectado a Internet o el servidor dynette está caído.",
|
||||||
|
"group_already_exist": "El grupo {group} ya existe",
|
||||||
|
"group_already_exist_on_system": "El grupo {group} ya existe en los grupos del sistema",
|
||||||
|
"group_cannot_be_deleted": "El grupo {group} no se puede eliminar manualmente.",
|
||||||
|
"group_user_already_in_group": "El usuario {user} ya está en el grupo {group}",
|
||||||
|
"group_user_not_in_group": "El usuario {user} no está en el grupo {group}",
|
||||||
|
"log_permission_create": "Crear permiso «{}»",
|
||||||
|
"log_permission_delete": "Eliminar permiso «{}»",
|
||||||
|
"log_user_group_create": "Crear grupo «{}»",
|
||||||
|
"log_user_permission_update": "Actualizar los accesos para el permiso «{}»",
|
||||||
|
"log_user_permission_reset": "Restablecer permiso «{}»",
|
||||||
|
"migration_0011_failed_to_remove_stale_object": "No se pudo eliminar el objeto obsoleto {dn}: {error}",
|
||||||
|
"permission_already_allowed": "El grupo «{group}» ya tiene el permiso «{permission}» activado",
|
||||||
|
"permission_already_disallowed": "El grupo «{group}» ya tiene el permiso «{permission}» desactivado",
|
||||||
|
"permission_cannot_remove_main": "No está permitido eliminar un permiso principal",
|
||||||
|
"user_already_exists": "El usuario «{user}» ya existe",
|
||||||
|
"app_full_domain_unavailable": "Lamentablemente esta aplicación tiene que instalarse en un dominio propio pero ya hay otras aplicaciones instaladas en el dominio «{domain}». Podría usar un subdomino dedicado a esta aplicación en su lugar.",
|
||||||
|
"app_install_failed": "No se pudo instalar {app}: {error}",
|
||||||
|
"app_install_script_failed": "Ha ocurrido un error en el guión de instalación de la aplicación",
|
||||||
|
"group_cannot_edit_all_users": "El grupo «all_users» no se puede editar manualmente. Es un grupo especial destinado a contener todos los usuarios registrados en YunoHost",
|
||||||
|
"group_cannot_edit_visitors": "El grupo «visitors» no se puede editar manualmente. Es un grupo especial que representa a los visitantes anónimos",
|
||||||
|
"group_cannot_edit_primary_group": "El grupo «{group}» no se puede editar manualmente. Es el grupo primario destinado a contener solo un usuario específico.",
|
||||||
|
"log_permission_url": "Actualizar la URL relacionada con el permiso «{}»",
|
||||||
|
"migration_0011_slapd_config_will_be_overwritten": "Parece que ha editado manualmente la configuración de slapd. Para esta migración crítica, YunoHost necesita forzar la actualización de la configuración de slapd. Los archivos originales se respaldarán en {conf_backup_folder}.",
|
||||||
|
"permission_already_up_to_date": "El permiso no se ha actualizado porque las peticiones de incorporación o eliminación ya coinciden con el estado actual.",
|
||||||
|
"permission_currently_allowed_for_all_users": "Este permiso se concede actualmente a todos los usuarios además de los otros grupos. Probablemente quiere o eliminar el permiso de «all_users» o eliminar los otros grupos a los que está otorgado actualmente.",
|
||||||
|
"permission_require_account": "El permiso {permission} solo tiene sentido para usuarios con una cuenta y, por lo tanto, no se puede activar para visitantes.",
|
||||||
|
"app_remove_after_failed_install": "Eliminando la aplicación tras el fallo de instalación…",
|
||||||
|
"diagnosis_basesystem_host": "El servidor está ejecutando Debian {debian_version}.",
|
||||||
|
"diagnosis_basesystem_kernel": "El servidor está ejecutando el núcleo de Linux {kernel_version}",
|
||||||
|
"diagnosis_basesystem_ynh_single_version": "{package} versión: {version} ({repo})",
|
||||||
|
"diagnosis_basesystem_ynh_main_version": "El servidor está ejecutando YunoHost {main_version} ({repo})",
|
||||||
|
"diagnosis_basesystem_ynh_inconsistent_versions": "Está ejecutando versiones incoherentes de los paquetes de YunoHost... probablemente por una actualización errónea o parcial.",
|
||||||
|
"diagnosis_failed_for_category": "Diagnóstico fallido para la categoría «{category}» : {error}",
|
||||||
|
"diagnosis_cache_still_valid": "(Caché aún válida para el diagnóstico de {category}. ¡Aún no se ha rediagnosticado!)",
|
||||||
|
"diagnosis_found_errors_and_warnings": "¡Encontrado(s) error(es) significativo(s) {errors} (y aviso(s) {warnings}) relacionado(s) con {category}!",
|
||||||
|
"diagnosis_display_tip_web": "Puede ir a la sección de diagnóstico (en la pantalla principal) para ver los problemas encontrados.",
|
||||||
|
"diagnosis_display_tip_cli": "Puede ejecutar «yunohost diagnosis show --issues» para mostrar los problemas encontrados.",
|
||||||
|
"apps_catalog_init_success": "¡Sistema de catálogo de aplicaciones inicializado!",
|
||||||
|
"apps_catalog_updating": "Actualizando catálogo de aplicaciones...",
|
||||||
|
"apps_catalog_failed_to_download": "No se pudo descargar el catálogo de aplicaciones {apps_catalog}: {error}",
|
||||||
|
"apps_catalog_obsolete_cache": "La caché del catálogo de aplicaciones está vacía u obsoleta.",
|
||||||
|
"apps_catalog_update_success": "¡El catálogo de aplicaciones ha sido actualizado!",
|
||||||
|
"diagnosis_cant_run_because_of_dep": "No se puede ejecutar el diagnóstico para {category} mientras haya problemas importantes relacionados con {dep}.",
|
||||||
|
"diagnosis_ignored_issues": "(+ {nb_ignored} problema(s) ignorado(s))",
|
||||||
|
"diagnosis_found_errors": "¡Encontrado(s) error(es) significativo(s) {errors} relacionado(s) con {category}!",
|
||||||
|
"diagnosis_found_warnings": "Encontrado elemento(s) {warnings} que puede(n) ser mejorado(s) para {category}.",
|
||||||
|
"diagnosis_everything_ok": "¡Todo se ve bien para {category}!",
|
||||||
|
"app_upgrade_script_failed": "Ha ocurrido un error en el script de actualización de la app",
|
||||||
|
"diagnosis_no_cache": "Todavía no hay una caché de diagnóstico para la categoría '{category}'",
|
||||||
|
"diagnosis_ip_no_ipv4": "El servidor no cuenta con ipv4 funcional.",
|
||||||
|
"diagnosis_ip_not_connected_at_all": "¿¡Está conectado el servidor a internet!?",
|
||||||
|
"diagnosis_ip_broken_resolvconf": "DNS parece no funcionar en tu servidor, lo que parece estar relacionado con /etc/resolv.conf no apuntando a 127.0.0.1.",
|
||||||
|
"diagnosis_dns_missing_record": "Según la configuración DNS recomendada, deberías añadir un registro DNS\ntipo: {type}\nnombre: {name}\nvalor: {value}",
|
||||||
|
"diagnosis_diskusage_low": "El almacenamiento {mountpoint} (en dispositivo {device}) solo tiene {free} ({free_percent}%) de espacio disponible. Ten cuidado.",
|
||||||
|
"diagnosis_services_bad_status_tip": "Puedes intentar reiniciar el servicio, y si no funciona, echar un vistazo a los logs del servicio usando 'yunohost service log {service}' o a través de la sección 'Servicios' en webadmin.",
|
||||||
|
"diagnosis_ip_connected_ipv6": "¡El servidor está conectado a internet a través de IPv6!",
|
||||||
|
"diagnosis_ip_no_ipv6": "El servidor no cuenta con IPv6 funcional.",
|
||||||
|
"diagnosis_ip_dnsresolution_working": "¡DNS no está funcionando!",
|
||||||
|
"diagnosis_ip_broken_dnsresolution": "Parece que no funciona la resolución de nombre de dominio por alguna razón... ¿Hay algún firewall bloqueando peticiones DNS?",
|
||||||
|
"diagnosis_ip_weird_resolvconf": "Parece que DNS funciona, pero ten cuidado, porque estás utilizando /etc/resolv.conf modificado.",
|
||||||
|
"diagnosis_ip_weird_resolvconf_details": "En su lugar, este fichero debería ser un enlace simbólico a /etc/resolvconf/run/resolv.conf apuntando a 127.0.0.1 (dnsmasq). Los servidores de nombre de domino deben configurarse a través de /etc/resolv.dnsmasq.conf.",
|
||||||
|
"diagnosis_dns_good_conf": "Buena configuración DNS para el dominio {domain} (categoría {category})",
|
||||||
|
"diagnosis_dns_bad_conf": "Configuración mala o faltante de los DNS para el dominio {domain} (categoría {category})",
|
||||||
|
"diagnosis_dns_discrepancy": "El registro DNS con tipo {type} y nombre {name} no se corresponde a la configuración recomendada.\nValor actual: {current}\nValor esperado: {value}",
|
||||||
|
"diagnosis_services_bad_status": "El servicio {service} está {status} :(",
|
||||||
|
"diagnosis_diskusage_verylow": "El almacenamiento {mountpoint} (en el dispositivo {device}) sólo tiene {free} ({free_percent}%) de espacio disponible. Deberías considerar la posibilidad de limpiar algo de espacio.",
|
||||||
|
"diagnosis_diskusage_ok": "¡El almacenamiento {mountpoint} (en el dispositivo {device}) todavía tiene {free} ({free_percent}%) de espacio libre!",
|
||||||
|
"diagnosis_services_conf_broken": "¡Mala configuración para el servicio {service}!",
|
||||||
|
"diagnosis_services_running": "¡El servicio {service} está en ejecución!",
|
||||||
|
"diagnosis_failed": "No se ha podido obtener el resultado del diagnóstico para la categoría '{category}': {error}",
|
||||||
|
"diagnosis_ip_connected_ipv4": "¡El servidor está conectado a internet a través de IPv4!",
|
||||||
|
"diagnosis_security_vulnerable_to_meltdown_details": "Para corregir esto, debieras actualizar y reiniciar tu sistema para cargar el nuevo kernel de Linux (o contacta tu proveedor si esto no funciona). Mas información en https://meltdownattack.com/",
|
||||||
|
"diagnosis_ram_verylow": "Al sistema le queda solamente {available} ({available_percent}%) de RAM! (De un total de {total})",
|
||||||
|
"diagnosis_ram_low": "Al sistema le queda {available} ({available_percent}%) de RAM de un total de {total}. Cuidado.",
|
||||||
|
"diagnosis_ram_ok": "El sistema aun tiene {available} ({available_percent}%) de RAM de un total de {total}.",
|
||||||
|
"diagnosis_swap_none": "El sistema no tiene mas espacio de intercambio. Considera agregar por lo menos {recommended} de espacio de intercambio para evitar que el sistema se quede sin memoria.",
|
||||||
|
"diagnosis_swap_notsomuch": "Al sistema le queda solamente {total} de espacio de intercambio. Considera agregar al menos {recommended} para evitar que el sistema se quede sin memoria.",
|
||||||
|
"diagnosis_mail_ougoing_port_25_ok": "El puerto de salida 25 no esta bloqueado y los correos electrónicos pueden ser enviados a otros servidores.",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked": "El puerto de salida 25 parece estar bloqueado. Intenta desbloquearlo con el panel de configuración de tu proveedor de servicios de Internet (o proveedor de halbergue). Mientras tanto, el servidor no podrá enviar correos electrónicos a otros servidores.",
|
||||||
|
"diagnosis_regenconf_allgood": "Todos los archivos de configuración están en linea con la configuración recomendada!",
|
||||||
|
"diagnosis_regenconf_manually_modified": "El archivo de configuración {file} fue modificado manualmente.",
|
||||||
|
"diagnosis_regenconf_manually_modified_details": "Esto este probablemente BIEN siempre y cuando sepas lo que estas haciendo ;) !",
|
||||||
|
"diagnosis_regenconf_manually_modified_debian": "El archivos de configuración {file} fue modificado manualmente comparado con el valor predeterminado de Debian.",
|
||||||
|
"diagnosis_regenconf_manually_modified_debian_details": "Esto este probablemente BIEN, pero igual no lo pierdas de vista...",
|
||||||
|
"diagnosis_security_all_good": "Ninguna vulnerabilidad critica de seguridad fue encontrada.",
|
||||||
|
"diagnosis_security_vulnerable_to_meltdown": "Pareces vulnerable a el colapso de vulnerabilidad critica de seguridad.",
|
||||||
|
"diagnosis_description_basesystem": "Sistema de base",
|
||||||
|
"diagnosis_description_ip": "Conectividad a Internet",
|
||||||
|
"diagnosis_description_dnsrecords": "Registro DNS",
|
||||||
|
"diagnosis_description_services": "Comprobación del estado de los servicios",
|
||||||
|
"diagnosis_description_ports": "Exposición de puertos",
|
||||||
|
"diagnosis_description_systemresources": "Recursos del sistema",
|
||||||
|
"diagnosis_swap_ok": "El sistema tiene {total} de espacio de intercambio!",
|
||||||
|
"diagnosis_ports_needed_by": "La apertura de este puerto es requerida para la funcionalidad {category} (service {service})",
|
||||||
|
"diagnosis_ports_ok": "El puerto {port} es accesible desde internet.",
|
||||||
|
"diagnosis_ports_unreachable": "El puerto {port} no es accesible desde internet.",
|
||||||
|
"diagnosis_ports_could_not_diagnose": "No se puede comprobar si los puertos están accesibles desde el exterior.",
|
||||||
|
"diagnosis_ports_could_not_diagnose_details": "Error: {error}",
|
||||||
|
"diagnosis_description_security": "Validación de seguridad",
|
||||||
|
"diagnosis_description_regenconf": "Configuraciones de sistema",
|
||||||
|
"diagnosis_description_mail": "Correo electrónico",
|
||||||
|
"diagnosis_description_web": "Web",
|
||||||
|
"diagnosis_basesystem_hardware_board": "El modelo de placa del servidor es {model}",
|
||||||
|
"diagnosis_basesystem_hardware": "La arquitectura material del servidor es {virt} {arch}",
|
||||||
|
"migration_description_0014_remove_app_status_json": "Supresión del archivo de aplicaciones heredado status.json",
|
||||||
|
"migration_description_0013_futureproof_apps_catalog_system": "Migración hacia el nuevo sistema de catalogo de aplicación a prueba del futuro",
|
||||||
|
"log_domain_main_domain": "Hacer de '{}' el dominio principal",
|
||||||
|
"log_app_config_apply": "Aplica la configuración de la aplicación '{}'",
|
||||||
|
"log_app_config_show_panel": "Muestra el panel de configuración de la aplicación '{}'",
|
||||||
|
"log_app_action_run": "Inicializa la acción de la aplicación '{}'",
|
||||||
|
"group_already_exist_on_system_but_removing_it": "El grupo {group} ya existe en el grupo de sistema, pero YunoHost lo suprimirá …",
|
||||||
|
"global_settings_setting_pop3_enabled": "Habilita el protocolo POP3 para el servidor de correo electrónico",
|
||||||
|
"domain_cannot_remove_main_add_new_one": "No se puede remover '{domain:s}' porque es su principal y único dominio. Primero debe agregar un nuevo dominio con la linea de comando 'yunohost domain add <another-domain.com>', entonces configurarlo como dominio principal con 'yunohost domain main-domain -n <another-domain.com>' y finalmente borrar el dominio '{domain:s}' con 'yunohost domain remove {domain:s}'.",
|
||||||
|
"diagnosis_never_ran_yet": "Este servidor todavía no tiene reportes de diagnostico. Puede iniciar un diagnostico completo desde la interface administrador web o con la linea de comando 'yunohost diagnosis run'.",
|
||||||
|
"diagnosis_unknown_categories": "Las siguientes categorías están desconocidas: {categories}",
|
||||||
|
"diagnosis_http_unreachable": "El dominio {domain} esta fuera de alcance desde internet y a través de HTTP.",
|
||||||
|
"diagnosis_http_bad_status_code": "El sistema de diagnostico no pudo comunicarse con su servidor. Puede ser otra maquina que contesto en lugar del servidor. Debería verificar en su firewall que el re-direccionamiento del puerto 80 esta correcto.",
|
||||||
|
"diagnosis_http_connection_error": "Error de conexión: Ne se pudo conectar al dominio solicitado,",
|
||||||
|
"diagnosis_http_timeout": "El intento de contactar a su servidor desde internet corrió fuera de tiempo. Al parece esta incomunicado. Debería verificar que nginx corre en el puerto 80, y que la redireción del puerto 80 no interfiere con en el firewall.",
|
||||||
|
"diagnosis_http_ok": "El Dominio {domain} es accesible desde internet a través de HTTP.",
|
||||||
|
"diagnosis_http_could_not_diagnose": "No se pudo verificar si el dominio es accesible desde internet.",
|
||||||
|
"diagnosis_http_could_not_diagnose_details": "Error: {error}",
|
||||||
|
"diagnosis_ports_forwarding_tip": "Para solucionar este incidente, debería configurar el \"port forwading\" en su router como especificado en https://yunohost.org/isp_box_config"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
{}
|
{
|
||||||
|
"password_too_simple_1": "Pasahitzak gutxienez 8 karaktere izan behar ditu"
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue