mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Compare commits
324 commits
debian/11.
...
dev
Author | SHA1 | Date | |
---|---|---|---|
|
a5049a8a13 | ||
|
6e84e3532a | ||
|
917cf251fb | ||
|
8a5f2808a1 | ||
68f35831e7 | |||
b91e9dd8f4 | |||
38b39ebaea | |||
ef17082768 | |||
e3ddb1dc4d | |||
|
5b37936d11 | ||
|
e82d20aa7b | ||
|
aff885e6b7 | ||
|
7a04462ccd | ||
|
606e246ec4 | ||
|
e3e8b903c7 | ||
|
488f563b45 | ||
|
3d4804be68 | ||
|
d4f774ad72 | ||
|
d8ab3e68a9 | ||
|
71b50549f5 | ||
|
a40874c305 | ||
|
9223d30a83 | ||
|
5ad9962757 | ||
|
4dfcc13a3f | ||
|
e11b61f49e | ||
|
243a34d2d5 | ||
|
ca2572d00b | ||
|
518c3bbbe2 | ||
|
9517b26c63 | ||
|
a6785d34bc | ||
|
7c79060467 | ||
|
007c13ce42 | ||
|
2102242a61 | ||
|
c409888a4b | ||
|
c14ebc8be4 | ||
|
9b0553580b | ||
|
bc2ed45e9d | ||
|
a76cd05e87 | ||
|
eb14e404d6 | ||
|
aae24614c4 | ||
|
51787a2f8b | ||
|
c5953b5420 | ||
|
4afff118e4 | ||
|
6113fde48a | ||
|
b734e2ea89 | ||
|
0a44d7cea4 | ||
|
5d3280c0fd | ||
|
8dc521a528 | ||
|
2e70143da2 | ||
|
3095496fe9 | ||
|
586d1c7f63 | ||
|
d63c61e0df | ||
|
4248b27b26 | ||
|
0f662d069c | ||
|
7ca710685e | ||
|
31d10079c7 | ||
|
980777ebf1 | ||
|
436826abf9 | ||
|
477fa63f46 | ||
|
9a6f7dac3b | ||
|
498006cab6 | ||
|
2f186b6f7f | ||
|
5708776df6 | ||
|
abdbb7efcd | ||
|
658ef88e47 | ||
|
4d5cc62540 | ||
|
f88e4cacdf | ||
|
36b9188aec | ||
|
c104dc6449 | ||
|
938e400865 | ||
|
de9980f31e | ||
|
f02d4a4376 | ||
|
92f4a605b8 | ||
|
df320a44cf | ||
|
6733526bee | ||
|
d0df3caed4 | ||
|
9083a5cc3d | ||
|
764fe6a7ba | ||
|
200f0272d5 | ||
|
9915559c40 | ||
|
760256f85d | ||
|
684c3d9b2c | ||
|
90c4034908 | ||
|
3deffdbd57 | ||
|
9f6f5f92fb | ||
|
e88ba3428c | ||
|
fe524dd866 | ||
|
65ea34d7cb | ||
|
d766f7cdda | ||
|
423e79bd57 | ||
|
44529b6d92 | ||
|
f4727d3cb6 | ||
|
8705dfcf5c | ||
|
ad98a10fa8 | ||
|
d376677db6 | ||
|
8b56983171 | ||
|
2d3dddc51a | ||
|
c861ef2ae6 | ||
|
53427e8c14 | ||
|
e5d74d420d | ||
|
cd30a2acc0 | ||
|
9e1b0561e3 | ||
|
843771ea05 | ||
|
ddf3e32c1c | ||
|
6d21e9fced | ||
|
d881d1a505 | ||
|
ebaecfcbd6 | ||
|
eeee096f3a | ||
|
fc168c54a1 | ||
|
b010219814 | ||
|
67c5edc40e | ||
|
437189d8c1 | ||
|
b2492ffc3d | ||
|
34861f906d | ||
|
a7edbc0cc7 | ||
|
b1d1f9f907 | ||
|
c90a691448 | ||
|
f6c270e1d2 | ||
|
3d53cf0467 | ||
|
7ee1734265 | ||
|
179daf68df | ||
|
57b4e240e1 | ||
|
bfbc7035dd | ||
|
239819b6da | ||
|
357896cd55 | ||
|
ded4892b9e | ||
|
9721685001 | ||
|
8395b066bc | ||
|
ac4ff0fc2d | ||
|
04101862ac | ||
|
0242ecd0e7 | ||
|
6e5c555e37 | ||
|
ebcf3c79ff | ||
|
f11f11973b | ||
|
67d6baa151 | ||
|
97bb6bde09 | ||
|
ca59886303 | ||
|
a8fd6afeee | ||
|
a5868733d7 | ||
|
079cdc2624 | ||
|
4232fc7c4b | ||
|
845a14bfe1 | ||
|
73e0d6c271 | ||
|
14312a9ec4 | ||
|
8a65053a59 | ||
|
64c8d9e853 | ||
|
22201863a1 | ||
|
bb20020c5a | ||
|
771a4b3446 | ||
|
beeddc7819 | ||
|
0907411efc | ||
|
d71d8fe7b3 | ||
|
9e8c7e704e | ||
|
85c5c04b15 | ||
|
a0bc7926c4 | ||
|
27ccd2918e | ||
|
588742f31b | ||
|
4112deda0c | ||
|
1e70577d23 | ||
|
623bd151d6 | ||
|
d87fe9fb4c | ||
|
bf8271e383 | ||
|
818fd78a3d | ||
|
eb012de188 | ||
|
725b41d2a3 | ||
|
85239f74f6 | ||
|
0b438eab02 | ||
|
3c992c894a | ||
|
a97c82d1c2 | ||
|
566213ecd5 | ||
|
5fb54936ba | ||
|
0b5c5a5f4d | ||
|
e8c171fd83 | ||
|
0bffcbae76 | ||
|
fbe42f1867 | ||
|
7121ed6836 | ||
|
e339006c69 | ||
|
a66890ddd8 | ||
|
e54e99bfb7 | ||
|
ab8e0e6619 | ||
|
401ccf69c7 | ||
|
e5bc94b9cf | ||
|
9c22d36c6f | ||
|
b266e398ff | ||
|
c8a18129df | ||
|
8be726b993 | ||
b96c530d2b | |||
bb25c6b15d | |||
|
a735a6d296 | ||
49961145ca | |||
b289de3eca | |||
26fba087d6 | |||
|
f6fbd69c39 | ||
|
1bb81e8f69 | ||
|
0f34d7e10f | ||
|
2763e04012 | ||
90d4cd99b9 | |||
f344cb037b | |||
|
c694ea2cbc | ||
|
772e772b24 | ||
|
b5e6f02d7d | ||
|
30286bc811 | ||
|
62f7e022ff | ||
|
ffde5cbf87 | ||
|
c6aec680b9 | ||
|
395dc6b843 | ||
|
fe8fcaefef | ||
|
d6aa310c21 | ||
|
5fcb1c6188 | ||
|
22d8c0c70a | ||
|
8de0a4cdcb | ||
|
6f73a82a2d | ||
|
ab742e55bb | ||
|
5d15c00d92 | ||
|
9a5aff9715 | ||
|
3e20cdd59e | ||
|
2edb6ad625 | ||
|
41ca422210 | ||
|
e55c914974 | ||
|
7c7e763a74 | ||
|
0f85ddbcff | ||
|
131760e30c | ||
|
7e55a791b6 | ||
|
2640dd3171 | ||
|
4e3f30ef82 | ||
|
bc3e36abb3 | ||
|
92807afb16 | ||
|
1ed56952e6 | ||
|
6b77e19bbd | ||
|
50034aabdd | ||
|
ef622ffe4d | ||
|
40a3205add | ||
|
7b0383f865 | ||
|
0783af306d | ||
|
36b3b00166 | ||
|
e75b4b3b3b | ||
|
1c62960e25 | ||
|
1e1409c7d7 | ||
|
fcaa366e91 | ||
|
f2b5f0f22c | ||
|
4b43d8d99d | ||
|
636c9e563e | ||
|
c0bccc3ac9 | ||
|
9727765ecf | ||
|
5ef0c84c0f | ||
|
c965f13f50 | ||
|
20741c63aa | ||
|
a48bfa67de | ||
|
3f973669fc | ||
|
a18d5f26f2 | ||
|
c2271ab731 | ||
|
eee84c5f66 | ||
|
6ed167bfaf | ||
|
eaf00103dd | ||
|
ff78f3ada7 | ||
|
fcbb971792 | ||
|
dbf579b7b4 | ||
|
e5b575901a | ||
|
d47c87e57d | ||
|
28603da4f1 | ||
|
c2d69f7f84 | ||
|
a349fc0334 | ||
|
3e1c9ebaf7 | ||
|
1ab3a79d39 | ||
|
44bbc34967 | ||
|
7b2959a3eb | ||
|
1dfc47d1d7 | ||
|
9cd7c86641 | ||
|
ef68485c5f | ||
|
656ff823a9 | ||
|
ae3018cdd0 | ||
|
8b8768fd77 | ||
|
75d7042974 | ||
|
3b26ccc2a5 | ||
|
3608c5678c | ||
|
d9d404a5b2 | ||
8846381d47 | |||
650481a58a | |||
|
87eedc2a36 | ||
|
feb9a095b3 | ||
|
997388dc79 | ||
|
9982a77582 | ||
|
2a7fefaecb | ||
|
7347b08e49 | ||
|
6851d740f7 | ||
|
2d26935079 | ||
|
094cd9ddd6 | ||
|
29ae71acad | ||
|
c9b76fde35 | ||
|
e3bebeac98 | ||
|
ed426f05ba | ||
|
2af4c157d9 | ||
|
0aad13cd2f | ||
|
2895d4d99b | ||
|
1fb80e5d24 | ||
|
30467f8bc3 | ||
|
d8c3ff4c8a | ||
|
0e4495f11e | ||
|
2b1f74268f | ||
|
5f6df6a859 | ||
|
b3409729a6 | ||
|
9298738d06 | ||
|
262453f132 | ||
|
d4857834f3 | ||
|
3942ea12ae | ||
|
a2ac77fa91 | ||
|
6ee40ac06a | ||
|
f26565d6de | ||
|
2e05b0894b | ||
|
18092db1c8 | ||
|
ecb82ec693 | ||
|
31ae5d1eaa | ||
|
be3df69326 | ||
|
7caf7e8b3e | ||
|
e558513609 | ||
|
3d728d90ce | ||
|
0bd69e5622 | ||
|
1b5074d857 | ||
|
dd8db1883a | ||
|
06c8fbc881 | ||
|
a25033bba5 | ||
|
307ed10c41 | ||
|
383fd6f5d4 | ||
|
bc30805c7d |
149 changed files with 6329 additions and 4069 deletions
|
@ -38,12 +38,17 @@ workflow:
|
||||||
- if: $CI_COMMIT_TAG # For tags
|
- if: $CI_COMMIT_TAG # For tags
|
||||||
- if: $CI_COMMIT_REF_NAME == "ci-format-$CI_DEFAULT_BRANCH" # Ignore black formatting branch created by the CI
|
- if: $CI_COMMIT_REF_NAME == "ci-format-$CI_DEFAULT_BRANCH" # Ignore black formatting branch created by the CI
|
||||||
when: never
|
when: never
|
||||||
|
- if: $CI_COMMIT_REF_NAME == "actions/black" # Ignore black formatting branch created by the CI
|
||||||
|
when: never
|
||||||
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "push" # If it's not the default branch and if it's a push, then do not trigger a build
|
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "push" # If it's not the default branch and if it's a push, then do not trigger a build
|
||||||
when: never
|
when: never
|
||||||
- when: always
|
- when: always
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
YNH_BUILD_DIR: "/ynh-build"
|
GIT_CLONE_PATH: '$CI_BUILDS_DIR/$CI_COMMIT_SHA/$CI_JOB_ID'
|
||||||
|
YNH_SOURCE: "https://github.com/yunohost"
|
||||||
|
YNH_DEBIAN: "bullseye"
|
||||||
|
YNH_SKIP_DIAGNOSIS_DURING_UPGRADE: "true"
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- template: Code-Quality.gitlab-ci.yml
|
- template: Code-Quality.gitlab-ci.yml
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
.build-stage:
|
.build-stage:
|
||||||
stage: build
|
stage: build
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
variables:
|
variables:
|
||||||
YNH_SOURCE: "https://github.com/yunohost"
|
YNH_BUILD_DIR: "$GIT_CLONE_PATH/build"
|
||||||
before_script:
|
before_script:
|
||||||
- mkdir -p $YNH_BUILD_DIR
|
- mkdir -p $YNH_BUILD_DIR
|
||||||
- DEBIAN_FRONTEND=noninteractive apt update
|
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- ./*.deb
|
- ./*.deb
|
||||||
|
|
||||||
.build_script: &build_script
|
.build_script: &build_script
|
||||||
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" install devscripts --no-install-recommends
|
|
||||||
- cd $YNH_BUILD_DIR/$PACKAGE
|
- cd $YNH_BUILD_DIR/$PACKAGE
|
||||||
- VERSION=$(dpkg-parsechangelog -S Version 2>/dev/null)
|
- VERSION=$(dpkg-parsechangelog -S Version 2>/dev/null)
|
||||||
- VERSION_NIGHTLY="${VERSION}+$(date +%Y%m%d%H%M)"
|
- VERSION_TIMESTAMPED="${VERSION}+$(date +%Y%m%d%H%M)"
|
||||||
- dch --package "${PACKAGE}" --force-bad-version -v "${VERSION_NIGHTLY}" -D "unstable" --force-distribution "Daily build."
|
- dch --package "${PACKAGE}" --force-bad-version -v "${VERSION_TIMESTAMPED}" -D "unstable" --force-distribution "CI build."
|
||||||
- debuild --no-lintian -us -uc
|
- debuild --no-lintian -us -uc
|
||||||
- cp $YNH_BUILD_DIR/*.deb ${CI_PROJECT_DIR}/
|
- cp $YNH_BUILD_DIR/*.deb ${CI_PROJECT_DIR}/
|
||||||
- cd ${CI_PROJECT_DIR}
|
- cd ${CI_PROJECT_DIR}
|
||||||
|
@ -36,14 +34,12 @@ build-yunohost:
|
||||||
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $YNH_BUILD_DIR/$PACKAGE
|
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $YNH_BUILD_DIR/$PACKAGE
|
||||||
- *build_script
|
- *build_script
|
||||||
|
|
||||||
|
|
||||||
build-ssowat:
|
build-ssowat:
|
||||||
extends: .build-stage
|
extends: .build-stage
|
||||||
variables:
|
variables:
|
||||||
PACKAGE: "ssowat"
|
PACKAGE: "ssowat"
|
||||||
script:
|
script:
|
||||||
- DEBIAN_DEPENDS=$(cat debian/control | tr "," "\n" | grep -Po "ssowat \([>,=,<]+ .*\)" | grep -Po "[0-9\.]+")
|
- git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE -b $YNH_DEBIAN $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE --depth 1
|
||||||
- git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE -b $DEBIAN_DEPENDS $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE --depth 1
|
|
||||||
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $YNH_BUILD_DIR/$PACKAGE
|
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $YNH_BUILD_DIR/$PACKAGE
|
||||||
- *build_script
|
- *build_script
|
||||||
|
|
||||||
|
@ -52,7 +48,6 @@ build-moulinette:
|
||||||
variables:
|
variables:
|
||||||
PACKAGE: "moulinette"
|
PACKAGE: "moulinette"
|
||||||
script:
|
script:
|
||||||
- DEBIAN_DEPENDS=$(cat debian/control | tr "," "\n" | grep -Po "moulinette \([>,=,<]+ .*\)" | grep -Po "[0-9\.]+")
|
- git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE -b $YNH_DEBIAN $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE --depth 1
|
||||||
- git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE -b $DEBIAN_DEPENDS $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE --depth 1
|
|
||||||
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $YNH_BUILD_DIR/$PACKAGE
|
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $YNH_BUILD_DIR/$PACKAGE
|
||||||
- *build_script
|
- *build_script
|
||||||
|
|
|
@ -4,18 +4,19 @@
|
||||||
|
|
||||||
generate-helpers-doc:
|
generate-helpers-doc:
|
||||||
stage: doc
|
stage: doc
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update -y && apt-get install git hub -y
|
|
||||||
- git config --global user.email "yunohost@yunohost.org"
|
- git config --global user.email "yunohost@yunohost.org"
|
||||||
- git config --global user.name "$GITHUB_USER"
|
- git config --global user.name "$GITHUB_USER"
|
||||||
script:
|
script:
|
||||||
- cd doc
|
- cd doc
|
||||||
- python3 generate_helper_doc.py
|
- python3 generate_helper_doc.py 2
|
||||||
|
- python3 generate_helper_doc.py 2.1
|
||||||
- python3 generate_resource_doc.py > resources.md
|
- python3 generate_resource_doc.py > resources.md
|
||||||
- hub clone https://$GITHUB_TOKEN:x-oauth-basic@github.com/YunoHost/doc.git doc_repo
|
- hub clone https://$GITHUB_TOKEN:x-oauth-basic@github.com/YunoHost/doc.git doc_repo
|
||||||
- cp helpers.md doc_repo/pages/06.contribute/10.packaging_apps/20.scripts/10.helpers/packaging_app_scripts_helpers.md
|
- cp helpers.v2.md doc_repo/pages/06.contribute/10.packaging_apps/20.scripts/10.helpers/packaging_app_scripts_helpers.md
|
||||||
|
- cp helpers.v2.1.md doc_repo/pages/06.contribute/10.packaging_apps/20.scripts/12.helpers21/packaging_app_scripts_helpers_v21.md
|
||||||
- cp resources.md doc_repo/pages/06.contribute/10.packaging_apps/10.manifest/10.appresources/packaging_app_manifest_resources.md
|
- cp resources.md doc_repo/pages/06.contribute/10.packaging_apps/10.manifest/10.appresources/packaging_app_manifest_resources.md
|
||||||
- cd doc_repo
|
- cd doc_repo
|
||||||
# replace ${CI_COMMIT_REF_NAME} with ${CI_COMMIT_TAG} ?
|
# replace ${CI_COMMIT_REF_NAME} with ${CI_COMMIT_TAG} ?
|
||||||
|
|
|
@ -14,9 +14,8 @@
|
||||||
|
|
||||||
upgrade:
|
upgrade:
|
||||||
extends: .install-stage
|
extends: .install-stage
|
||||||
image: "after-install"
|
image: "core-tests"
|
||||||
script:
|
script:
|
||||||
- apt-get update -o Acquire::Retries=3
|
|
||||||
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ${CI_PROJECT_DIR}/*.deb
|
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ${CI_PROJECT_DIR}/*.deb
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,6 +23,5 @@ install-postinstall:
|
||||||
extends: .install-stage
|
extends: .install-stage
|
||||||
image: "before-install"
|
image: "before-install"
|
||||||
script:
|
script:
|
||||||
- apt-get update -o Acquire::Retries=3
|
|
||||||
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ${CI_PROJECT_DIR}/*.deb
|
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ${CI_PROJECT_DIR}/*.deb
|
||||||
- yunohost tools postinstall -d domain.tld -u syssa -F 'Syssa Mine' -p the_password --ignore-dyndns --force-diskspace
|
- yunohost tools postinstall -d domain.tld -u syssa -F 'Syssa Mine' -p the_password --ignore-dyndns --force-diskspace
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
lint39:
|
lint39:
|
||||||
stage: lint
|
stage: lint
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
script:
|
script:
|
||||||
|
@ -13,14 +13,14 @@ lint39:
|
||||||
|
|
||||||
invalidcode39:
|
invalidcode39:
|
||||||
stage: lint
|
stage: lint
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
- tox -e py39-invalidcode
|
- tox -e py39-invalidcode
|
||||||
|
|
||||||
mypy:
|
mypy:
|
||||||
stage: lint
|
stage: lint
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
- tox -e py39-mypy
|
- tox -e py39-mypy
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
.install_debs: &install_debs
|
.install_debs: &install_debs
|
||||||
- apt-get update -o Acquire::Retries=3
|
|
||||||
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ${CI_PROJECT_DIR}/*.deb
|
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ${CI_PROJECT_DIR}/*.deb
|
||||||
- pip3 install -U mock pip pytest pytest-cov pytest-mock pytest-sugar requests-mock tox ansi2html black jinja2 "packaging<22"
|
|
||||||
|
|
||||||
.test-stage:
|
.test-stage:
|
||||||
stage: test
|
stage: test
|
||||||
image: "after-install"
|
image: "core-tests"
|
||||||
variables:
|
variables:
|
||||||
PYTEST_ADDOPTS: "--color=yes"
|
PYTEST_ADDOPTS: "--color=yes"
|
||||||
before_script:
|
before_script:
|
||||||
|
@ -34,6 +32,7 @@ full-tests:
|
||||||
PYTEST_ADDOPTS: "--color=yes"
|
PYTEST_ADDOPTS: "--color=yes"
|
||||||
before_script:
|
before_script:
|
||||||
- *install_debs
|
- *install_debs
|
||||||
|
- pip install mock pip pyOpenSSL pytest pytest-cov pytest-mock pytest-sugar requests-mock "packaging<22"
|
||||||
- yunohost tools postinstall -d domain.tld -u syssa -F 'Syssa Mine' -p the_password --ignore-dyndns --force-diskspace
|
- yunohost tools postinstall -d domain.tld -u syssa -F 'Syssa Mine' -p the_password --ignore-dyndns --force-diskspace
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest --cov=yunohost tests/ src/tests/ --junitxml=report.xml
|
- python3 -m pytest --cov=yunohost tests/ src/tests/ --junitxml=report.xml
|
||||||
|
@ -57,14 +56,17 @@ test-actionmap:
|
||||||
changes:
|
changes:
|
||||||
- share/actionsmap.yml
|
- share/actionsmap.yml
|
||||||
|
|
||||||
test-helpers:
|
test-helpers2:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- cd tests
|
- cd tests
|
||||||
- bash test_helpers.sh
|
- bash test_helpers.sh
|
||||||
# only:
|
|
||||||
# changes:
|
test-helpers2.1:
|
||||||
# - helpers/*
|
extends: .test-stage
|
||||||
|
script:
|
||||||
|
- cd tests
|
||||||
|
- bash test_helpers.sh 2.1
|
||||||
|
|
||||||
test-domains:
|
test-domains:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
|
|
|
@ -13,10 +13,9 @@ test-i18n-keys:
|
||||||
|
|
||||||
autofix-translated-strings:
|
autofix-translated-strings:
|
||||||
stage: translation
|
stage: translation
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update -y && apt-get install git hub -y
|
|
||||||
- git config --global user.email "yunohost@yunohost.org"
|
- git config --global user.email "yunohost@yunohost.org"
|
||||||
- git config --global user.name "$GITHUB_USER"
|
- git config --global user.name "$GITHUB_USER"
|
||||||
- hub clone --branch ${CI_COMMIT_REF_NAME} "https://$GITHUB_TOKEN:x-oauth-basic@github.com/YunoHost/yunohost.git" github_repo
|
- hub clone --branch ${CI_COMMIT_REF_NAME} "https://$GITHUB_TOKEN:x-oauth-basic@github.com/YunoHost/yunohost.git" github_repo
|
||||||
|
|
|
@ -69,7 +69,7 @@ then
|
||||||
You should now proceed with YunoHost post-installation. This is where you will
|
You should now proceed with YunoHost post-installation. This is where you will
|
||||||
be asked for:
|
be asked for:
|
||||||
- the main domain of your server;
|
- the main domain of your server;
|
||||||
- the administration password.
|
- the username and password for the first admin
|
||||||
|
|
||||||
You can perform this step:
|
You can perform this step:
|
||||||
- from your web browser, by accessing: https://yunohost.local/ or ${local_ip}
|
- from your web browser, by accessing: https://yunohost.local/ or ${local_ip}
|
||||||
|
|
|
@ -84,4 +84,3 @@ module:hook("stanza/iq/jabber:iq:auth:query", function(event)
|
||||||
end
|
end
|
||||||
return true;
|
return true;
|
||||||
end);
|
end);
|
||||||
|
|
||||||
|
|
|
@ -211,3 +211,11 @@ smtp_sasl_security_options = noanonymous
|
||||||
# where to find sasl_passwd
|
# where to find sasl_passwd
|
||||||
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
|
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if backup_mx_domains != "" %}
|
||||||
|
# Backup MX (secondary MX)
|
||||||
|
relay_domains = $mydestination {{backup_mx_domains}}
|
||||||
|
relay_recipient_maps = hash:/etc/postfix/relay_recipients
|
||||||
|
maximal_queue_lifetime = 20d
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ SLAPD_PIDFILE=
|
||||||
# sockets.
|
# sockets.
|
||||||
# Example usage:
|
# Example usage:
|
||||||
# SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
|
# SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
|
||||||
SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
|
SLAPD_SERVICES="ldap://localhost:389/ ldaps:/// ldapi:///"
|
||||||
|
|
||||||
# If SLAPD_NO_START is set, the init script will not start or restart
|
# If SLAPD_NO_START is set, the init script will not start or restart
|
||||||
# slapd (but stop will still work). Uncomment this if you are
|
# slapd (but stop will still work). Uncomment this if you are
|
||||||
|
|
|
@ -84,7 +84,7 @@ Subsystem sftp internal-sftp
|
||||||
|
|
||||||
# Apply following instructions to user with sftp perm only
|
# Apply following instructions to user with sftp perm only
|
||||||
Match Group sftp.main,!ssh.main
|
Match Group sftp.main,!ssh.main
|
||||||
ForceCommand internal-sftp
|
ForceCommand internal-sftp -u 0002
|
||||||
# We can't restrict to /home/%u because the chroot base must be owned by root
|
# We can't restrict to /home/%u because the chroot base must be owned by root
|
||||||
# So we chroot only on /home
|
# So we chroot only on /home
|
||||||
# See https://serverfault.com/questions/584986/bad-ownership-or-modes-for-chroot-directory-component
|
# See https://serverfault.com/questions/584986/bad-ownership-or-modes-for-chroot-directory-component
|
||||||
|
@ -97,7 +97,7 @@ Match Group sftp.main,!ssh.main
|
||||||
PermitUserRC no
|
PermitUserRC no
|
||||||
|
|
||||||
Match Group sftp.app,!ssh.app
|
Match Group sftp.app,!ssh.app
|
||||||
ForceCommand internal-sftp
|
ForceCommand internal-sftp -u 0002
|
||||||
ChrootDirectory %h
|
ChrootDirectory %h
|
||||||
AllowTcpForwarding no
|
AllowTcpForwarding no
|
||||||
AllowStreamLocalForwarding no
|
AllowStreamLocalForwarding no
|
||||||
|
|
228
debian/changelog
vendored
228
debian/changelog
vendored
|
@ -1,3 +1,231 @@
|
||||||
|
yunohost (11.2.30) stable; urgency=low
|
||||||
|
|
||||||
|
- helpers v2.1: check if patches dir exists before getting realpath ([#1938](http://github.com/YunoHost/yunohost/pull/1938))
|
||||||
|
- helpers v2.1: ynh_add_swap and ynh_smart_mktemp (aff885e6b)
|
||||||
|
- helpers v2.1: fix ynh_restore_everything ([#1943](http://github.com/YunoHost/yunohost/pull/1943))
|
||||||
|
- helpers v2.1: fix typo in docs: ynh_install_app_dependencies -> ynh_apt_install_dependencies ([#1939](http://github.com/YunoHost/yunohost/pull/1939))
|
||||||
|
- helpers: fix syntax, disambiguate subshell syntax ([#1940](http://github.com/YunoHost/yunohost/pull/1940))
|
||||||
|
- quality: Add maintenante/shfmt.sh for shell script formatting (68f35831e)
|
||||||
|
- quality: Apply shfmt everywhere, fix tabs/space/indent (8a5f2808a, e3ddb1dc4, ef1708276, 38b39ebae, b91e9dd8f)
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Félix Piédallu, Josué Tille, OniriCorpe, selfhoster1312)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sat, 31 Aug 2024 19:26:59 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.29) stable; urgency=low
|
||||||
|
|
||||||
|
- apps: generalize replacing __INSTALL_DIR__ and __APP__ in config panel 'bind' statement to any setting (9b0553580)
|
||||||
|
- apps/config panels: move the computation of the actual 'bind' value to the python core (a6785d34b)
|
||||||
|
- perf: add cache for _get_app_settings() (c14ebc8be, 7c7906046)
|
||||||
|
- quality: use _assert_is_installed for consistency instead of if not _is_intalled(app): raise (c409888a4)
|
||||||
|
- i18n: Translations updated for Basque, French, Galician, Greek, Indonesian
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (cjdw, craftrac, José M, ppr, xabirequejo)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 27 Aug 2024 14:46:26 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.28) stable; urgency=low
|
||||||
|
|
||||||
|
- ci: various changes due to CI infrastructure changes (200f0272d, 764fe6a7b, 9083a5cc3, d0df3caed, 6733526be, df320a44c, 92f4a605b, f02d4a437, c5953b542)
|
||||||
|
- apps: exclude .well-known subpaths from conflict checks ([#1647](http://github.com/YunoHost/yunohost/pull/1647))
|
||||||
|
- apps: in apt resource, fix empty string in packages_from_raw_bash breaking dpkg-build (a76cd05e8)
|
||||||
|
- sftp: Tweak umask for SFTP ([#1384](http://github.com/YunoHost/yunohost/pull/1384))
|
||||||
|
- mail: Be able to use postfix as a backup ("secondary") MX hosts ([#1253](http://github.com/YunoHost/yunohost/pull/1253))
|
||||||
|
- diagnosis: Add check regarding rfkill blocking Wi-Fi card on RPi ([#1841](http://github.com/YunoHost/yunohost/pull/1841))
|
||||||
|
- users: trigger hooks when adding or removing user into group (51787a2f8)
|
||||||
|
- i18n: Translations updated for Basque, French, Indonesian, Russian
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (cjdw, Emmanuel Averty, Ivan Davydov, ljf, ppr, Tagada, tituspijean, xabirequejo)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sun, 25 Aug 2024 13:17:43 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.27) stable; urgency=low
|
||||||
|
|
||||||
|
- apt resource: fix handling of empty 'packages' list breaking dpkg-deb call (3deffdbd5)
|
||||||
|
- i18n: Translations updated for Indonesian, Turkish
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Ali Çırçır, cjdw)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sat, 03 Aug 2024 18:41:27 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.26) stable; urgency=low
|
||||||
|
|
||||||
|
- bullseye->bookworm: encourage apt to remove luajit if it's installed because for some reason it's causing issues (423e79bd5)
|
||||||
|
- bullseye->bookworm: have a specific step dedicated to upgrade python3.9 to 3.11 because apt(itude) is derping about it sometimes... (d766f7cdd)
|
||||||
|
- bullseye->bookworm: boring tweak to remove chattr +i from /etc/resolv.conf otherwise resolvconf will later explode and complain about it (65ea34d7c)
|
||||||
|
- Fix yunomprompt not being enable after ISO install (fe524dd86)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 01 Aug 2024 18:05:33 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.25) stable; urgency=low
|
||||||
|
|
||||||
|
- diagnosis: be more robust when diagnosis DMARC records not containing '=' (d376677db)
|
||||||
|
- bullseye->bookworm: explicitly import _strptime at the beginning to try to prevent "No module named '_strptime'" during migration (2d3dddc51)
|
||||||
|
- bullseye->bookworm: explicitly validate that we're on yunohost 12.x at the end of the migration (8b5698317)
|
||||||
|
- bullseye->bookworm: make sure the non-free / non-free-firmware stuff is idempotent (ad98a10fa)
|
||||||
|
- bullseye->bookworm: in debian control, add rule that moulinette and ssowat must be < 12 to prevent situation in bullseye->bookworm transition where moulinette gets upgrade but yunohost doesnt and everything explodes (8705dfcf5)
|
||||||
|
- bullseye->bookworm: more stuff to try to prevent aptitude derping about python dependencies (f4727d3cb)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 30 Jul 2024 17:12:12 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.24) stable; urgency=low
|
||||||
|
|
||||||
|
- ci: we don't care about mypy in tests/ folder (ebaecfcbd)
|
||||||
|
- helpers: fix install from equivs ([#1921](http://github.com/YunoHost/yunohost/pull/1921))
|
||||||
|
- bullseye->bookworm: re-add tweak about libluajit2 + be more robust about full-upgrade that may fail if python3.9-venv aint installed (9e1b0561e)
|
||||||
|
- i18n: Translations updated for Indonesian
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (cjdw, Kayou)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 26 Jul 2024 21:01:23 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.23) stable; urgency=low
|
||||||
|
|
||||||
|
- helpers2.1: force sourcing getopts before the other helpers to prevent stupid issues (in particular when renaming phpversion to php_version) (3d53cf04)
|
||||||
|
- diagnosis: Remove SenderScore from the dnsbl_list.yml file ([#1918](http://github.com/YunoHost/yunohost/pull/1918))
|
||||||
|
- ldap: make slapd listen also on ipv6 ([#1916](http://github.com/YunoHost/yunohost/pull/1916))
|
||||||
|
- log: zzz fix log list again (b2492ffc)
|
||||||
|
- i18n: Translations updated for Galician, Indonesian, Slovak
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (cjdw, Étienne Deparis, José M, Jose Riha, Josué Tille)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 23 Jul 2024 19:07:20 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.22) stable; urgency=low
|
||||||
|
|
||||||
|
- logs: fix "log list" : use root_dir for iglob / make sure we use absolute paths ([#1913](http://github.com/YunoHost/yunohost/pull/1913))
|
||||||
|
- bullseye->bookworm: remove pkg_resources from pip freeze ([#1912](http://github.com/YunoHost/yunohost/pull/1912))
|
||||||
|
- bullseye->bookworm: explicitly install yunohost-portal (4232fc7c)
|
||||||
|
- bullseye->bookworm: explicitly remove python3.9 and python3.9-venv which seems to confuse aptitude... (079cdc26)
|
||||||
|
- bullseye->bookworm: try the yunohost upgrade without unholding the app-ynh-deps virtual packages, then after unholding if it didnt work for some reason (a8fd6afe)
|
||||||
|
- bullseye->bookworm: automatically add non-free-firmware if non-free is enabled (97bb6bde)
|
||||||
|
- bullseye->bookworm: trigger the 'new' migrations from inside the bullseye->bookworm migration (f11f1197)
|
||||||
|
- i18n: Translations updated for Basque, French, Indonesian
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Anonymous, cjdw, Kayou, ppr, xabirequejo)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 19 Jul 2024 16:51:55 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.21.2) stable; urgency=low
|
||||||
|
|
||||||
|
- bullseye->bookworm migration: tweak message to reflect the fact that metronome and rspamd will be applications starting with bookworm (64c8d9e8)
|
||||||
|
- helpers/apt: unbound variable (8a65053a)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 15 Jul 2024 23:07:08 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.21.1) stable; urgency=low
|
||||||
|
|
||||||
|
- helpers2.1: forgot to patch ynh_remove_fpm_config -> ynh_config_remove_phpfpm (bb20020c)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 15 Jul 2024 22:13:39 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.21) stable; urgency=low
|
||||||
|
|
||||||
|
- log: optimize log list perf by creating a 'cache' symlink pointing to the log's parent ([#1907](http://github.com/YunoHost/yunohost/pull/1907))
|
||||||
|
- log: small hack when dumping log right after script failure, prevent a weird edge case where it'll dump the log of the resource provisioning instead of the script (1bb81e8f)
|
||||||
|
- debian: Bullseye->Bookworm migration ('hidden' but easier to test) ([#1759](http://github.com/YunoHost/yunohost/pull/1759), ab8e0e66, e54e99bf)
|
||||||
|
- helpers/apt: rely on simpler dpkg-deb --build rather than equivs to create .deb for app virtual dependencies (f6fbd69c, 8be726b9)
|
||||||
|
- helpers/apt: Support apt repositories with [trusted=yes] ([#1903](http://github.com/YunoHost/yunohost/pull/1903))
|
||||||
|
- backups: one should be able to restore a backup archive by providing a path to the archive without moving it to /home/yunohost.backup/archives/ (c8a18129, b266e398)
|
||||||
|
- backups: yunohost should not ask confirmation that 'YunoHost is already installed' when restoring only apps (9c22d36c)
|
||||||
|
- i18n: translate _diagnosis_ignore function ([#1894](http://github.com/YunoHost/yunohost/pull/1894))
|
||||||
|
- i18n: Translations updated for Basque, Catalan, French, Galician, German, Indonesian, Japanese, Russian, Spanish, Ukrainian
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (alexAubin, Anonymous, cjdw, Félix Piédallu, Ivan Davydov, José M, Kayou, OniriCorpe, ppr, Zwiebel)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 15 Jul 2024 16:22:26 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.20.2) stable; urgency=low
|
||||||
|
|
||||||
|
- Fix service enable/disable auto-ignoring diagnosis entries ([#1886](http://github.com/YunoHost/yunohost/pull/1886))
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (OniriCorpe)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Wed, 03 Jul 2024 21:51:50 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.20.1) stable; urgency=low
|
||||||
|
|
||||||
|
- helpers2.1: typo (1ed56952e)
|
||||||
|
- helpers2.1: add unit tests (92807afb1)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 01 Jul 2024 23:38:29 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.20) stable; urgency=low
|
||||||
|
|
||||||
|
- helpers2.1: fix automigration of phpversion to php_version (3f973669)
|
||||||
|
- helpers2.1: change source patches location + raise an error instead of a warning when a patch fails to apply on CI (a48bfa67)
|
||||||
|
- helpers2.1: when using ynh_die, also return the error via YNH_STDRETURN such that it can be obtained from the python and displayed in the main error message, to increase the chance that people may read it and have something more useful than "An error happened in the script" (f2b5f0f2)
|
||||||
|
- helpers2.1: remove the ynh_clean_setup mechanism underused/useless.. (1c62960e)
|
||||||
|
- helpers2.1: switch to posisional args for ynh_multimedia_addaccess because that's what 99% of apps already do (ef622ffe)
|
||||||
|
- helpers2.1: add support for downloading .tar files ([#1889](http://github.com/YunoHost/yunohost/pull/1889))
|
||||||
|
- services/diagnosis: automatically ignore the service in diagnosis if it has been deactivated with the ynh cli ([#1886](http://github.com/YunoHost/yunohost/pull/1886))
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (alexAubin, OniriCorpe, Sebastian Gumprich)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 01 Jul 2024 18:46:52 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.19) stable; urgency=low
|
||||||
|
|
||||||
|
- apps: tweaks to be more robust and prevent the stupid flood of 'sh: 0: getcwd() failed: No such file or directory' when running an app upgrade/remove from /var/www/$app, sometimes making it look like the upgrade failed when it didnt (a349fc03)
|
||||||
|
- apps: be more robust when an app upgrade succeeds but for some reason is marked with 'broke the system' ... ending up in inconsistent state between the app settings vs the app scritpts (for example in v1->v2 transitions but not only) (e5b57590)
|
||||||
|
- helpers2.1: Fix getopts error handling ... (3e1c9eba)
|
||||||
|
- helpers2.1: also run _ynh_apply_default_permissions in ynh_restore to be consistent (also because the user uid on the new system may be different than in the archive etc) (eee84c5f)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sat, 29 Jun 2024 23:55:52 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.18) stable; urgency=low
|
||||||
|
|
||||||
|
- helpers2.1: Rework _ynh_apply_default_permissions to hopefully remove the necessity to chown/chmod in the app scripts ([#1883](http://github.com/YunoHost/yunohost/pull/1883))
|
||||||
|
- helpers2.1: in logrotate, make sure to also chown $app the log dir (1dfc47d1d)
|
||||||
|
- helpers2.1: forgot to rename the apt call in mongodb helpers (7b2959a3e)
|
||||||
|
- helpers2.1: in ynh_safe_rm, check if target is not a broken symlink before erorring out ([#1716](http://github.com/YunoHost/yunohost/pull/1716))
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (Félix Piédallu)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sat, 29 Jun 2024 18:05:04 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.17.1) stable; urgency=low
|
||||||
|
|
||||||
|
- helpers2.1: fix __PATH__/ handling (997388dc)
|
||||||
|
- ci: Fix helpers 2.1 doc location (7347b08e)
|
||||||
|
- helpers/doc: De-hide some helpers v1 in documentation now that the structure is less bloated sort of ? (2a7fefae)
|
||||||
|
- helpers/doc: fix detail block, cant use the HTML <details> because grav doesnt interpret markdown in it (feb9a095)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 25 Jun 2024 14:19:58 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.17) stable; urgency=low
|
||||||
|
|
||||||
|
- helpers: Misc cleaning / reorganizing to prepare new doc (2895d4d9)
|
||||||
|
- helpers: rework helper doc now that we have multiple versions of helpers in parallel + improve structure (group helper file in categories) (094cd9dd)
|
||||||
|
- helpers/mongo: less noisy output when checking the avx flag is here in /proc/cpuinfo (2af4c157)
|
||||||
|
- apps/helpers2.1: fix app env in resource upgrade context ending up in incorrect helper version being used (ed426f05)
|
||||||
|
- helpers2.1: forgot to propagate the 'goenv latest' fix from helpers v1 (d8c3ff4c)
|
||||||
|
- helpers2.1: drop ynh_apps helper because only a single app is using it ... (1fb80e5d)
|
||||||
|
- helpers2.1: other typo fixes
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Mon, 24 Jun 2024 22:36:32 +0200
|
||||||
|
|
||||||
|
yunohost (11.2.16) stable; urgency=low
|
||||||
|
|
||||||
|
- apps/logs: fix some information not being redacted because of the packaging v2 flows (a25033bb)
|
||||||
|
- logs: misc ad-hoc tweaks to limit the noise in log sharing (06c8fbc8)
|
||||||
|
- helpers: (1/2/2.1) add a new ynh_app_setting_set_default to replace the unecessarily complex 'if [ -z ${foo:-} ]' trick ([#1873](http://github.com/YunoHost/yunohost/pull/1873))
|
||||||
|
- helpers2.1: drop unused 'local source' mechanism from ynh_setup_source (dd8db188)
|
||||||
|
- helpers2.1: fix positional arg parsing in ynh_psql_create_user (e5585136)
|
||||||
|
- helpers2.1: rework the fpm usage/footprint madness ([#1874](http://github.com/YunoHost/yunohost/pull/1874))
|
||||||
|
- helpers2.1: fix ynh_config_add_logrotate when no arg is passed (3942ea12)
|
||||||
|
- helpers2.1: sudo -u$app -> sudo -u $app (d4857834)
|
||||||
|
- helpers2.1: change default timeout of ynh_systemctl to 60s instead of 300s (262453f1)
|
||||||
|
- helpers2.1: display 100 lines instead of 20 in CI context when service fails to start (9298738d)
|
||||||
|
- helpers2.1: when using ynh_systemctl to reload/start/restart a service with a wait_until and it timesout, handle it as a failure rather than keep going (b3409729)
|
||||||
|
- helpers2.1: for some reason sudo -E doesn't preserve PATH even though it's exported, so we gotta explicitly use --preserve-env=PATH (5f6df6a8)
|
||||||
|
- helpers2.1: var rename / cosmetic etc for nodejs/ruby/go version and install directories (2b1f7426)
|
||||||
|
- i18n: Translations updated for Basque, Slovak
|
||||||
|
|
||||||
|
Thanks to all contributors <3 ! (alexAubin, Jose Riha, xabirequejo)
|
||||||
|
|
||||||
|
-- Alexandre Aubin <alex.aubin@mailoo.org> Sun, 23 Jun 2024 15:30:22 +0200
|
||||||
|
|
||||||
yunohost (11.2.15) stable; urgency=low
|
yunohost (11.2.15) stable; urgency=low
|
||||||
|
|
||||||
- apps: new experimentals "2.1" helpers ([#1855](http://github.com/YunoHost/yunohost/pull/1855))
|
- apps: new experimentals "2.1" helpers ([#1855](http://github.com/YunoHost/yunohost/pull/1855))
|
||||||
|
|
6
debian/control
vendored
6
debian/control
vendored
|
@ -10,14 +10,14 @@ Package: yunohost
|
||||||
Essential: yes
|
Essential: yes
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: ${python3:Depends}, ${misc:Depends}
|
Depends: ${python3:Depends}, ${misc:Depends}
|
||||||
, moulinette (>= 11.1), ssowat (>= 11.1)
|
, moulinette (>= 11.1), moulinette (<< 12.0), ssowat (>= 11.1), ssowat (<< 12.0)
|
||||||
, python3-psutil, python3-requests, python3-dnspython, python3-openssl
|
, python3-psutil, python3-requests, python3-dnspython, python3-openssl
|
||||||
, python3-miniupnpc, python3-dbus, python3-jinja2
|
, python3-miniupnpc, python3-dbus, python3-jinja2
|
||||||
, python3-toml, python3-packaging, python3-publicsuffix2
|
, python3-toml, python3-packaging, python3-publicsuffix2
|
||||||
, python3-ldap, python3-zeroconf (>= 0.36), python3-lexicon,
|
, python3-ldap, python3-zeroconf (>= 0.36), python3-lexicon,
|
||||||
, python-is-python3
|
, python-is-python3
|
||||||
, nginx, nginx-extras (>=1.18)
|
, nginx, nginx-extras (>=1.18)
|
||||||
, apt, apt-transport-https, apt-utils, dirmngr
|
, apt, apt-transport-https, apt-utils, aptitude, dirmngr
|
||||||
, openssh-server, iptables, fail2ban, bind9-dnsutils
|
, openssh-server, iptables, fail2ban, bind9-dnsutils
|
||||||
, openssl, ca-certificates, netcat-openbsd, iproute2
|
, openssl, ca-certificates, netcat-openbsd, iproute2
|
||||||
, slapd, ldap-utils, sudo-ldap, libnss-ldapd, unscd, libpam-ldapd
|
, slapd, ldap-utils, sudo-ldap, libnss-ldapd, unscd, libpam-ldapd
|
||||||
|
@ -28,7 +28,7 @@ Depends: ${python3:Depends}, ${misc:Depends}
|
||||||
, redis-server
|
, redis-server
|
||||||
, acl
|
, acl
|
||||||
, git, curl, wget, cron, unzip, jq, bc, at, procps, j2cli
|
, git, curl, wget, cron, unzip, jq, bc, at, procps, j2cli
|
||||||
, lsb-release, haveged, fake-hwclock, equivs, lsof, whois
|
, lsb-release, haveged, fake-hwclock, lsof, whois
|
||||||
Recommends: yunohost-admin
|
Recommends: yunohost-admin
|
||||||
, ntp, inetutils-ping | iputils-ping
|
, ntp, inetutils-ping | iputils-ping
|
||||||
, bash-completion, rsyslog
|
, bash-completion, rsyslog
|
||||||
|
|
2
debian/postinst
vendored
2
debian/postinst
vendored
|
@ -27,7 +27,7 @@ do_configure() {
|
||||||
yunohost tools migrations run --auto
|
yunohost tools migrations run --auto
|
||||||
|
|
||||||
echo "Re-diagnosing server health..."
|
echo "Re-diagnosing server health..."
|
||||||
yunohost diagnosis run --force
|
[[ -n "${YNH_SKIP_DIAGNOSIS_DURING_UPGRADE:-}" ]] && echo "(Skipping)" || yunohost diagnosis run --force
|
||||||
|
|
||||||
echo "Refreshing app catalog..."
|
echo "Refreshing app catalog..."
|
||||||
yunohost tools update apps --output-as none || true
|
yunohost tools update apps --output-as none || true
|
||||||
|
|
|
@ -1,10 +1,55 @@
|
||||||
#!/usr/env/python3
|
#!/usr/env/python3
|
||||||
|
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import glob
|
import glob
|
||||||
import datetime
|
import datetime
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
tree = {
|
||||||
|
"sources": {
|
||||||
|
"title": "Sources",
|
||||||
|
"notes": "This is coupled to the 'sources' resource in the manifest.toml",
|
||||||
|
"subsections": ["sources"],
|
||||||
|
},
|
||||||
|
"tech": {
|
||||||
|
"title": "App technologies",
|
||||||
|
"notes": "These allow to install specific version of the technology required to run some apps",
|
||||||
|
"subsections": ["nodejs", "ruby", "go", "composer"],
|
||||||
|
},
|
||||||
|
"db": {
|
||||||
|
"title": "Databases",
|
||||||
|
"notes": "This is coupled to the 'database' resource in the manifest.toml - at least for mysql/postgresql. Mongodb/redis may have better integration in the future.",
|
||||||
|
"subsections": ["mysql", "postgresql", "mongodb", "redis"],
|
||||||
|
},
|
||||||
|
"conf": {
|
||||||
|
"title": "Configurations / templating",
|
||||||
|
"subsections": [
|
||||||
|
"templating",
|
||||||
|
"nginx",
|
||||||
|
"php",
|
||||||
|
"systemd",
|
||||||
|
"fail2ban",
|
||||||
|
"logrotate",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"misc": {
|
||||||
|
"title": "Misc tools",
|
||||||
|
"subsections": [
|
||||||
|
"utils",
|
||||||
|
"setting",
|
||||||
|
"string",
|
||||||
|
"backup",
|
||||||
|
"logging",
|
||||||
|
"multimedia",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"meh": {
|
||||||
|
"title": "Deprecated or handled by the core / app resources since v2",
|
||||||
|
"subsections": ["permission", "apt", "systemuser"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_current_commit():
|
def get_current_commit():
|
||||||
p = subprocess.Popen(
|
p = subprocess.Popen(
|
||||||
|
@ -19,14 +64,7 @@ def get_current_commit():
|
||||||
return current_commit
|
return current_commit
|
||||||
|
|
||||||
|
|
||||||
def render(helpers):
|
def render(tree, helpers_version):
|
||||||
current_commit = get_current_commit()
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"helpers": helpers,
|
|
||||||
"date": datetime.datetime.now().strftime("%d/%m/%Y"),
|
|
||||||
"version": open("../debian/changelog").readlines()[0].split()[1].strip("()"),
|
|
||||||
}
|
|
||||||
|
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
from ansi2html import Ansi2HTMLConverter
|
from ansi2html import Ansi2HTMLConverter
|
||||||
|
@ -42,12 +80,15 @@ def render(helpers):
|
||||||
t = Template(template)
|
t = Template(template)
|
||||||
t.globals["now"] = datetime.datetime.utcnow
|
t.globals["now"] = datetime.datetime.utcnow
|
||||||
result = t.render(
|
result = t.render(
|
||||||
current_commit=current_commit,
|
tree=tree,
|
||||||
data=data,
|
date=datetime.datetime.now().strftime("%d/%m/%Y"),
|
||||||
|
version=open("../debian/changelog").readlines()[0].split()[1].strip("()"),
|
||||||
|
helpers_version=helpers_version,
|
||||||
|
current_commit=get_current_commit(),
|
||||||
convert=shell_to_html,
|
convert=shell_to_html,
|
||||||
shell_css=shell_css,
|
shell_css=shell_css,
|
||||||
)
|
)
|
||||||
open("helpers.md", "w").write(result)
|
open(f"helpers.v{helpers_version}.md", "w").write(result)
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
@ -87,7 +128,7 @@ class Parser:
|
||||||
# We're still in a comment bloc
|
# We're still in a comment bloc
|
||||||
assert line.startswith("# ") or line == "#", malformed_error(i)
|
assert line.startswith("# ") or line == "#", malformed_error(i)
|
||||||
current_block["comments"].append(line[2:])
|
current_block["comments"].append(line[2:])
|
||||||
elif line.strip() == "":
|
elif line.strip() == "" or line.startswith("_ynh"):
|
||||||
# Well eh that was not an actual helper definition ... start over ?
|
# Well eh that was not an actual helper definition ... start over ?
|
||||||
current_reading = "void"
|
current_reading = "void"
|
||||||
current_block = {
|
current_block = {
|
||||||
|
@ -121,7 +162,11 @@ class Parser:
|
||||||
# (we ignore helpers containing [internal] ...)
|
# (we ignore helpers containing [internal] ...)
|
||||||
if (
|
if (
|
||||||
"[packagingv1]" not in current_block["comments"]
|
"[packagingv1]" not in current_block["comments"]
|
||||||
and "[internal]" not in current_block["comments"]
|
and not any(
|
||||||
|
line.startswith("[internal]")
|
||||||
|
for line in current_block["comments"]
|
||||||
|
)
|
||||||
|
and not current_block["name"].startswith("_")
|
||||||
):
|
):
|
||||||
self.blocks.append(current_block)
|
self.blocks.append(current_block)
|
||||||
current_block = {
|
current_block = {
|
||||||
|
@ -212,23 +257,27 @@ def malformed_error(line_number):
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
helper_files = sorted(glob.glob("../helpers/*"))
|
|
||||||
helpers = []
|
|
||||||
|
|
||||||
for helper_file in helper_files:
|
if len(sys.argv) == 1:
|
||||||
if not os.path.isfile(helper_file):
|
print("This script needs the helper version (1, 2, 2.1) as an argument")
|
||||||
continue
|
sys.exit(1)
|
||||||
|
|
||||||
category_name = os.path.basename(helper_file)
|
version = sys.argv[1]
|
||||||
print("Parsing %s ..." % category_name)
|
|
||||||
|
for section in tree.values():
|
||||||
|
section["helpers"] = {}
|
||||||
|
for subsection in section["subsections"]:
|
||||||
|
print(f"Parsing {subsection} ...")
|
||||||
|
helper_file = f"../helpers/helpers.v{version}.d/{subsection}"
|
||||||
|
assert os.path.isfile(helper_file), f"Uhoh, {file} doesn't exists?"
|
||||||
p = Parser(helper_file)
|
p = Parser(helper_file)
|
||||||
p.parse_blocks()
|
p.parse_blocks()
|
||||||
for b in p.blocks:
|
for b in p.blocks:
|
||||||
p.parse_block(b)
|
p.parse_block(b)
|
||||||
|
|
||||||
helpers.append((category_name, p.blocks))
|
section["helpers"][subsection] = p.blocks
|
||||||
|
|
||||||
render(helpers)
|
render(tree, version)
|
||||||
|
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1,18 +1,26 @@
|
||||||
---
|
---
|
||||||
title: App helpers
|
title: App helpers (v{{ helpers_version }})
|
||||||
template: docs
|
template: docs
|
||||||
taxonomy:
|
taxonomy:
|
||||||
category: docs
|
category: docs
|
||||||
routes:
|
routes:
|
||||||
default: '/packaging_apps_helpers'
|
default: '/packaging_apps_helpers{% if helpers_version not in ["1", "2"] %}_v{{ helpers_version }}{% endif %}'
|
||||||
---
|
---
|
||||||
|
|
||||||
Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/{{ current_commit }}/doc/generate_helper_doc.py) on {{data.date}} (YunoHost version {{data.version}})
|
Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/{{ current_commit }}/doc/generate_helper_doc.py) on {{date}} (YunoHost version {{version}})
|
||||||
|
|
||||||
{% for category, helpers in data.helpers %}
|
|
||||||
## {{ category.upper() }}
|
{% for section_id, section in tree.items() %}
|
||||||
|
## {{ section["title"].title() }}
|
||||||
|
|
||||||
|
{% if section['notes'] %}<p>{{ section['notes'] }}</p>{% endif %}
|
||||||
|
|
||||||
|
{% for subsection, helpers in section["helpers"].items() %}
|
||||||
|
|
||||||
|
### {{ subsection.upper() }}
|
||||||
{% for h in helpers %}
|
{% for h in helpers %}
|
||||||
### {{ h.name }}
|
#### {{ h.name }}
|
||||||
|
|
||||||
[details summary="<i>{{ h.brief }}</i>" class="helper-card-subtitle text-muted"]
|
[details summary="<i>{{ h.brief }}</i>" class="helper-card-subtitle text-muted"]
|
||||||
|
|
||||||
**Usage**: `{{ h.usage }}`
|
**Usage**: `{{ h.usage }}`
|
||||||
|
@ -51,9 +59,9 @@ Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/{{
|
||||||
**Details**:
|
**Details**:
|
||||||
{{ h.details }}
|
{{ h.details }}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
[Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/{{ current_commit }}/helpers/{{ category }}#L{{ h.line + 1 }})
|
[Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/{{ current_commit }}/helpers/helpers.v{{ helpers_version if helpers_version != "2" else "1" }}.d/{{ subsection }}#L{{ h.line + 1 }})
|
||||||
[/details]
|
[/details]
|
||||||
|
{% endfor %}
|
||||||
---
|
---
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -13,6 +13,7 @@ YNH_HELPERS_DIR="$SCRIPT_DIR/helpers.v${YNH_HELPERS_VERSION}.d"
|
||||||
case "$YNH_HELPERS_VERSION" in
|
case "$YNH_HELPERS_VERSION" in
|
||||||
"1" | "2" | "2.1")
|
"1" | "2" | "2.1")
|
||||||
readarray -t HELPERS < <(find -L "$YNH_HELPERS_DIR" -mindepth 1 -maxdepth 1 -type f)
|
readarray -t HELPERS < <(find -L "$YNH_HELPERS_DIR" -mindepth 1 -maxdepth 1 -type f)
|
||||||
|
source $YNH_HELPERS_DIR/getopts
|
||||||
for helper in "${HELPERS[@]}"; do
|
for helper in "${HELPERS[@]}"; do
|
||||||
[ -r "$helper" ] && source "$helper"
|
[ -r "$helper" ] && source "$helper"
|
||||||
done
|
done
|
||||||
|
@ -20,6 +21,7 @@ case "$YNH_HELPERS_VERSION" in
|
||||||
*)
|
*)
|
||||||
echo "Helpers are not available in version '$YNH_HELPERS_VERSION'." >&2
|
echo "Helpers are not available in version '$YNH_HELPERS_VERSION'." >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
eval "$XTRACE_ENABLE"
|
eval "$XTRACE_ENABLE"
|
||||||
|
|
|
@ -19,8 +19,7 @@ ynh_install_apps() {
|
||||||
local apps_dependencies=""
|
local apps_dependencies=""
|
||||||
|
|
||||||
# For each app
|
# For each app
|
||||||
for one_app_and_its_args in "${apps_list[@]}"
|
for one_app_and_its_args in "${apps_list[@]}"; do
|
||||||
do
|
|
||||||
# Retrieve the name of the app (part before ?)
|
# Retrieve the name of the app (part before ?)
|
||||||
local one_app=$(cut -d "?" -f1 <<< "$one_app_and_its_args")
|
local one_app=$(cut -d "?" -f1 <<< "$one_app_and_its_args")
|
||||||
[ -z "$one_app" ] && ynh_die --message="You didn't provided a YunoHost app to install"
|
[ -z "$one_app" ] && ynh_die --message="You didn't provided a YunoHost app to install"
|
||||||
|
@ -28,8 +27,7 @@ ynh_install_apps() {
|
||||||
yunohost tools update apps
|
yunohost tools update apps
|
||||||
|
|
||||||
# Installing or upgrading the app depending if it's installed or not
|
# Installing or upgrading the app depending if it's installed or not
|
||||||
if ! yunohost app list --output-as json --quiet | jq -e --arg id $one_app '.apps[] | select(.id == $id)' >/dev/null
|
if ! yunohost app list --output-as json --quiet | jq -e --arg id $one_app '.apps[] | select(.id == $id)' > /dev/null; then
|
||||||
then
|
|
||||||
# Retrieve the arguments of the app (part after ?)
|
# Retrieve the arguments of the app (part after ?)
|
||||||
local one_argument=""
|
local one_argument=""
|
||||||
if [[ "$one_app_and_its_args" == *"?"* ]]; then
|
if [[ "$one_app_and_its_args" == *"?"* ]]; then
|
||||||
|
@ -44,8 +42,7 @@ ynh_install_apps() {
|
||||||
yunohost app upgrade $one_app
|
yunohost app upgrade $one_app
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -z "$apps_dependencies" ]
|
if [ ! -z "$apps_dependencies" ]; then
|
||||||
then
|
|
||||||
apps_dependencies="$apps_dependencies, $one_app"
|
apps_dependencies="$apps_dependencies, $one_app"
|
||||||
else
|
else
|
||||||
apps_dependencies="$one_app"
|
apps_dependencies="$one_app"
|
||||||
|
@ -67,31 +64,26 @@ ynh_remove_apps() {
|
||||||
local apps_dependencies=$(ynh_app_setting_get --app=$app --key=apps_dependencies)
|
local apps_dependencies=$(ynh_app_setting_get --app=$app --key=apps_dependencies)
|
||||||
ynh_app_setting_delete --app=$app --key=apps_dependencies
|
ynh_app_setting_delete --app=$app --key=apps_dependencies
|
||||||
|
|
||||||
if [ ! -z "$apps_dependencies" ]
|
if [ ! -z "$apps_dependencies" ]; then
|
||||||
then
|
|
||||||
# Split the list of apps dependencies in an array
|
# Split the list of apps dependencies in an array
|
||||||
local apps_dependencies_list=($(echo $apps_dependencies | tr ", " "\n"))
|
local apps_dependencies_list=($(echo $apps_dependencies | tr ", " "\n"))
|
||||||
|
|
||||||
# For each apps dependencies
|
# For each apps dependencies
|
||||||
for one_app in "${apps_dependencies_list[@]}"
|
for one_app in "${apps_dependencies_list[@]}"; do
|
||||||
do
|
|
||||||
# Retrieve the list of installed apps
|
# Retrieve the list of installed apps
|
||||||
local installed_apps_list=$(yunohost app list --output-as json --quiet | jq -r .apps[].id)
|
local installed_apps_list=$(yunohost app list --output-as json --quiet | jq -r .apps[].id)
|
||||||
local required_by=""
|
local required_by=""
|
||||||
local installed_app_required_by=""
|
local installed_app_required_by=""
|
||||||
|
|
||||||
# For each other installed app
|
# For each other installed app
|
||||||
for one_installed_app in $installed_apps_list
|
for one_installed_app in $installed_apps_list; do
|
||||||
do
|
|
||||||
# Retrieve the other apps dependencies
|
# Retrieve the other apps dependencies
|
||||||
one_installed_apps_dependencies=$(ynh_app_setting_get --app=$one_installed_app --key=apps_dependencies)
|
one_installed_apps_dependencies=$(ynh_app_setting_get --app=$one_installed_app --key=apps_dependencies)
|
||||||
if [ ! -z "$one_installed_apps_dependencies" ]
|
if [ ! -z "$one_installed_apps_dependencies" ]; then
|
||||||
then
|
|
||||||
one_installed_apps_dependencies_list=($(echo $one_installed_apps_dependencies | tr ", " "\n"))
|
one_installed_apps_dependencies_list=($(echo $one_installed_apps_dependencies | tr ", " "\n"))
|
||||||
|
|
||||||
# For each dependency of the other apps
|
# For each dependency of the other apps
|
||||||
for one_installed_app_dependency in "${one_installed_apps_dependencies_list[@]}"
|
for one_installed_app_dependency in "${one_installed_apps_dependencies_list[@]}"; do
|
||||||
do
|
|
||||||
if [[ $one_installed_app_dependency == $one_app ]]; then
|
if [[ $one_installed_app_dependency == $one_app ]]; then
|
||||||
required_by="$required_by $one_installed_app"
|
required_by="$required_by $one_installed_app"
|
||||||
fi
|
fi
|
||||||
|
@ -100,8 +92,7 @@ ynh_remove_apps() {
|
||||||
done
|
done
|
||||||
|
|
||||||
# If $one_app is no more required
|
# If $one_app is no more required
|
||||||
if [[ -z "$required_by" ]]
|
if [[ -z "$required_by" ]]; then
|
||||||
then
|
|
||||||
# Remove $one_app
|
# Remove $one_app
|
||||||
ynh_print_info --message="Removing of $one_app"
|
ynh_print_info --message="Removing of $one_app"
|
||||||
yunohost app remove $one_app --purge
|
yunohost app remove $one_app --purge
|
||||||
|
@ -134,16 +125,14 @@ ynh_spawn_app_shell() {
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
# Force Bash to be used to run this helper
|
# Force Bash to be used to run this helper
|
||||||
if [[ ! $0 =~ \/?bash$ ]]
|
if [[ ! $0 =~ \/?bash$ ]]; then
|
||||||
then
|
|
||||||
ynh_print_err --message="Please use Bash as shell"
|
ynh_print_err --message="Please use Bash as shell"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make sure the app is installed
|
# Make sure the app is installed
|
||||||
local installed_apps_list=($(yunohost app list --output-as json --quiet | jq -r .apps[].id))
|
local installed_apps_list=($(yunohost app list --output-as json --quiet | jq -r .apps[].id))
|
||||||
if [[ " ${installed_apps_list[*]} " != *" ${app} "* ]]
|
if [[ " ${installed_apps_list[*]} " != *" ${app} "* ]]; then
|
||||||
then
|
|
||||||
ynh_print_err --message="$app is not in the apps list"
|
ynh_print_err --message="$app is not in the apps list"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -156,49 +145,44 @@ ynh_spawn_app_shell() {
|
||||||
|
|
||||||
# Make sure the app has an install_dir setting
|
# Make sure the app has an install_dir setting
|
||||||
local install_dir=$(ynh_app_setting_get --app=$app --key=install_dir)
|
local install_dir=$(ynh_app_setting_get --app=$app --key=install_dir)
|
||||||
if [ -z "$install_dir" ]
|
if [ -z "$install_dir" ]; then
|
||||||
then
|
|
||||||
ynh_print_err --message="$app has no install_dir setting (does it use packaging format >=2?)"
|
ynh_print_err --message="$app has no install_dir setting (does it use packaging format >=2?)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Load the app's service name, or default to $app
|
# Load the app's service name, or default to $app
|
||||||
local service=$(ynh_app_setting_get --app=$app --key=service)
|
local service=$(ynh_app_setting_get --app=$app --key=service)
|
||||||
[ -z "$service" ] && service=$app;
|
[ -z "$service" ] && service=$app
|
||||||
|
|
||||||
# Export HOME variable
|
# Export HOME variable
|
||||||
export HOME=$install_dir;
|
export HOME=$install_dir
|
||||||
|
|
||||||
# Load the Environment variables from the app's service
|
# Load the Environment variables from the app's service
|
||||||
local env_var=$(systemctl show $service.service -p "Environment" --value)
|
local env_var=$(systemctl show $service.service -p "Environment" --value)
|
||||||
[ -n "$env_var" ] && export $env_var;
|
[ -n "$env_var" ] && export $env_var
|
||||||
|
|
||||||
# Force `php` to its intended version
|
# Force `php` to its intended version
|
||||||
# We use `eval`+`export` since `alias` is not propagated to subshells, even with `export`
|
# We use `eval`+`export` since `alias` is not propagated to subshells, even with `export`
|
||||||
local phpversion=$(ynh_app_setting_get --app=$app --key=phpversion)
|
local phpversion=$(ynh_app_setting_get --app=$app --key=phpversion)
|
||||||
local phpflags=$(ynh_app_setting_get --app=$app --key=phpflags)
|
local phpflags=$(ynh_app_setting_get --app=$app --key=phpflags)
|
||||||
if [ -n "$phpversion" ]
|
if [ -n "$phpversion" ]; then
|
||||||
then
|
|
||||||
eval "php() { php${phpversion} ${phpflags} \"\$@\"; }"
|
eval "php() { php${phpversion} ${phpflags} \"\$@\"; }"
|
||||||
export -f php
|
export -f php
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Source the EnvironmentFiles from the app's service
|
# Source the EnvironmentFiles from the app's service
|
||||||
local env_files=($(systemctl show $service.service -p "EnvironmentFiles" --value))
|
local env_files=($(systemctl show $service.service -p "EnvironmentFiles" --value))
|
||||||
if [ ${#env_files[*]} -gt 0 ]
|
if [ ${#env_files[*]} -gt 0 ]; then
|
||||||
then
|
|
||||||
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
|
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
|
||||||
set -a
|
set -a
|
||||||
for file in ${env_files[*]}
|
for file in ${env_files[*]}; do
|
||||||
do
|
|
||||||
[[ $file = /* ]] && source $file
|
[[ $file = /* ]] && source $file
|
||||||
done
|
done
|
||||||
set +a
|
set +a
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Activate the Python environment, if it exists
|
# Activate the Python environment, if it exists
|
||||||
if [ -f $install_dir/venv/bin/activate ]
|
if [ -f $install_dir/venv/bin/activate ]; then
|
||||||
then
|
|
||||||
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
|
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
|
||||||
set -a
|
set -a
|
||||||
source $install_dir/venv/bin/activate
|
source $install_dir/venv/bin/activate
|
||||||
|
@ -207,7 +191,7 @@ ynh_spawn_app_shell() {
|
||||||
|
|
||||||
# cd into the WorkingDirectory set in the service, or default to the install_dir
|
# cd into the WorkingDirectory set in the service, or default to the install_dir
|
||||||
local env_dir=$(systemctl show $service.service -p "WorkingDirectory" --value)
|
local env_dir=$(systemctl show $service.service -p "WorkingDirectory" --value)
|
||||||
[ -z $env_dir ] && env_dir=$install_dir;
|
[ -z $env_dir ] && env_dir=$install_dir
|
||||||
cd $env_dir
|
cd $env_dir
|
||||||
|
|
||||||
# Spawn the app shell
|
# Spawn the app shell
|
||||||
|
|
|
@ -186,22 +186,25 @@ ynh_package_install_from_equivs() {
|
||||||
|
|
||||||
# Build and install the package
|
# Build and install the package
|
||||||
local TMPDIR=$(mktemp --directory)
|
local TMPDIR=$(mktemp --directory)
|
||||||
|
mkdir -p ${TMPDIR}/${pkgname}/DEBIAN/
|
||||||
# Make sure to delete the legacy compat file
|
# For some reason, dpkg-deb insists for folder perm to be 755 and sometimes it's 777 o_O?
|
||||||
# It's now handle somewhat magically through the control file
|
chmod -R 755 ${TMPDIR}/${pkgname}
|
||||||
rm -f /usr/share/equivs/template/debian/compat
|
|
||||||
|
|
||||||
# Note that the cd executes into a sub shell
|
# Note that the cd executes into a sub shell
|
||||||
# Create a fake deb package with equivs-build and the given control file
|
# Create a fake deb package with equivs-build and the given control file
|
||||||
# Install the fake package without its dependencies with dpkg
|
# Install the fake package without its dependencies with dpkg
|
||||||
# Install missing dependencies with ynh_package_install
|
# Install missing dependencies with ynh_package_install
|
||||||
ynh_wait_dpkg_free
|
ynh_wait_dpkg_free
|
||||||
cp "$controlfile" "${TMPDIR}/control"
|
|
||||||
(
|
cp "$controlfile" "${TMPDIR}/${pkgname}/DEBIAN/control"
|
||||||
cd "$TMPDIR"
|
|
||||||
LC_ALL=C equivs-build ./control 2>&1
|
# Install the fake package without its dependencies with dpkg --force-depends
|
||||||
LC_ALL=C dpkg --force-depends --install "./${pkgname}_${pkgversion}_all.deb" 2>&1 | tee ./dpkg_log
|
if ! LC_ALL=C dpkg-deb --build "${TMPDIR}/${pkgname}" "${TMPDIR}/${pkgname}.deb" > "${TMPDIR}/dpkg_log" 2>&1; then
|
||||||
)
|
cat "${TMPDIR}/dpkg_log" >&2
|
||||||
|
ynh_die --message="Unable to install dependencies"
|
||||||
|
fi
|
||||||
|
# Don't crash in case of error, because is nicely covered by the following line
|
||||||
|
LC_ALL=C dpkg --force-depends --install "${TMPDIR}/${pkgname}.deb" 2>&1 | tee "${TMPDIR}/dpkg_log" || true
|
||||||
|
|
||||||
ynh_package_install --fix-broken \
|
ynh_package_install --fix-broken \
|
||||||
|| { # If the installation failed
|
|| { # If the installation failed
|
||||||
|
@ -224,8 +227,6 @@ YNH_INSTALL_APP_DEPENDENCIES_REPLACE="true"
|
||||||
|
|
||||||
# Define and install dependencies with a equivs control file
|
# Define and install dependencies with a equivs control file
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# This helper can/should only be called once per app
|
# This helper can/should only be called once per app
|
||||||
#
|
#
|
||||||
# example : ynh_install_app_dependencies dep1 dep2 "dep3|dep4|dep5"
|
# example : ynh_install_app_dependencies dep1 dep2 "dep3|dep4|dep5"
|
||||||
|
@ -265,8 +266,7 @@ ynh_install_app_dependencies() {
|
||||||
# The (?<=php) syntax corresponds to lookbehind ;)
|
# The (?<=php) syntax corresponds to lookbehind ;)
|
||||||
local specific_php_version=$(echo $dependencies | grep -oP '(?<=php)[0-9.]+(?=-|\>|)' | sort -u)
|
local specific_php_version=$(echo $dependencies | grep -oP '(?<=php)[0-9.]+(?=-|\>|)' | sort -u)
|
||||||
|
|
||||||
if [[ -n "$specific_php_version" ]]
|
if [[ -n "$specific_php_version" ]]; then
|
||||||
then
|
|
||||||
# Cover a small edge case where a packager could have specified "php7.4-pwet php5-gni" which is confusing
|
# Cover a small edge case where a packager could have specified "php7.4-pwet php5-gni" which is confusing
|
||||||
[[ $(echo $specific_php_version | wc -l) -eq 1 ]] \
|
[[ $(echo $specific_php_version | wc -l) -eq 1 ]] \
|
||||||
|| ynh_die --message="Inconsistent php versions in dependencies ... found : $specific_php_version"
|
|| ynh_die --message="Inconsistent php versions in dependencies ... found : $specific_php_version"
|
||||||
|
@ -280,8 +280,7 @@ ynh_install_app_dependencies() {
|
||||||
local old_php_fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir)
|
local old_php_fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir)
|
||||||
local old_php_finalphpconf="$old_php_fpm_config_dir/pool.d/$app.conf"
|
local old_php_finalphpconf="$old_php_fpm_config_dir/pool.d/$app.conf"
|
||||||
|
|
||||||
if [[ -f "$old_php_finalphpconf" ]]
|
if [[ -f "$old_php_finalphpconf" ]]; then
|
||||||
then
|
|
||||||
ynh_backup_if_checksum_is_different --file="$old_php_finalphpconf"
|
ynh_backup_if_checksum_is_different --file="$old_php_finalphpconf"
|
||||||
ynh_remove_fpm_config
|
ynh_remove_fpm_config
|
||||||
fi
|
fi
|
||||||
|
@ -290,8 +289,7 @@ ynh_install_app_dependencies() {
|
||||||
ynh_app_setting_set --app=$app --key=phpversion --value=$specific_php_version
|
ynh_app_setting_set --app=$app --key=phpversion --value=$specific_php_version
|
||||||
|
|
||||||
# Set the default php version back as the default version for php-cli.
|
# Set the default php version back as the default version for php-cli.
|
||||||
if test -e /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
if test -e /usr/bin/php$YNH_DEFAULT_PHP_VERSION; then
|
||||||
then
|
|
||||||
update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
||||||
fi
|
fi
|
||||||
elif grep --quiet 'php' <<< "$dependencies"; then
|
elif grep --quiet 'php' <<< "$dependencies"; then
|
||||||
|
@ -305,13 +303,11 @@ ynh_install_app_dependencies() {
|
||||||
# upgrade script where ynh_install_app_dependencies is called with this
|
# upgrade script where ynh_install_app_dependencies is called with this
|
||||||
# expected effect) Otherwise, any subsequent call will add dependencies
|
# expected effect) Otherwise, any subsequent call will add dependencies
|
||||||
# to those already present in the equivs control file.
|
# to those already present in the equivs control file.
|
||||||
if [[ $YNH_INSTALL_APP_DEPENDENCIES_REPLACE == "true" ]]
|
if [[ $YNH_INSTALL_APP_DEPENDENCIES_REPLACE == "true" ]]; then
|
||||||
then
|
|
||||||
YNH_INSTALL_APP_DEPENDENCIES_REPLACE="false"
|
YNH_INSTALL_APP_DEPENDENCIES_REPLACE="false"
|
||||||
else
|
else
|
||||||
local current_dependencies=""
|
local current_dependencies=""
|
||||||
if ynh_package_is_installed --package="${dep_app}-ynh-deps"
|
if ynh_package_is_installed --package="${dep_app}-ynh-deps"; then
|
||||||
then
|
|
||||||
current_dependencies="$(dpkg-query --show --showformat='${Depends}' ${dep_app}-ynh-deps) "
|
current_dependencies="$(dpkg-query --show --showformat='${Depends}' ${dep_app}-ynh-deps) "
|
||||||
current_dependencies=${current_dependencies// | /|}
|
current_dependencies=${current_dependencies// | /|}
|
||||||
fi
|
fi
|
||||||
|
@ -323,8 +319,9 @@ Section: misc
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Package: ${dep_app}-ynh-deps
|
Package: ${dep_app}-ynh-deps
|
||||||
Version: ${version}
|
Version: ${version}
|
||||||
Depends: ${dependencies}
|
Depends: ${dependencies//,,/,}
|
||||||
Architecture: all
|
Architecture: all
|
||||||
|
Maintainer: root@localhost
|
||||||
Description: Fake package for ${app} (YunoHost app) dependencies
|
Description: Fake package for ${app} (YunoHost app) dependencies
|
||||||
This meta-package is only responsible of installing its dependencies.
|
This meta-package is only responsible of installing its dependencies.
|
||||||
EOF
|
EOF
|
||||||
|
@ -335,8 +332,7 @@ EOF
|
||||||
|
|
||||||
# Trigger postgresql regenconf if we may have just installed postgresql
|
# Trigger postgresql regenconf if we may have just installed postgresql
|
||||||
local psql_installed2="$(ynh_package_is_installed "postgresql-$PSQL_VERSION" && echo yes || echo no)"
|
local psql_installed2="$(ynh_package_is_installed "postgresql-$PSQL_VERSION" && echo yes || echo no)"
|
||||||
if [[ "$psql_installed" != "$psql_installed2" ]]
|
if [[ "$psql_installed" != "$psql_installed2" ]]; then
|
||||||
then
|
|
||||||
yunohost tools regen-conf postgresql
|
yunohost tools regen-conf postgresql
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -364,8 +360,6 @@ ynh_add_app_dependencies() {
|
||||||
|
|
||||||
# Remove fake package and its dependencies
|
# Remove fake package and its dependencies
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# Dependencies will removed only if no other package need them.
|
# Dependencies will removed only if no other package need them.
|
||||||
#
|
#
|
||||||
# usage: ynh_remove_app_dependencies
|
# usage: ynh_remove_app_dependencies
|
||||||
|
@ -382,24 +376,20 @@ ynh_remove_app_dependencies() {
|
||||||
|
|
||||||
# Edge case where the app dep may be on hold,
|
# Edge case where the app dep may be on hold,
|
||||||
# cf https://forum.yunohost.org/t/migration-error-cause-of-ffsync/20675/4
|
# cf https://forum.yunohost.org/t/migration-error-cause-of-ffsync/20675/4
|
||||||
if apt-mark showhold | grep -q -w ${dep_app}-ynh-deps
|
if apt-mark showhold | grep -q -w ${dep_app}-ynh-deps; then
|
||||||
then
|
|
||||||
apt-mark unhold ${dep_app}-ynh-deps
|
apt-mark unhold ${dep_app}-ynh-deps
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Remove the fake package and its dependencies if they not still used.
|
# Remove the fake package and its dependencies if they not still used.
|
||||||
# (except if dpkg doesn't know anything about the package,
|
# (except if dpkg doesn't know anything about the package,
|
||||||
# which should be symptomatic of a failed install, and we don't want bash to report an error)
|
# which should be symptomatic of a failed install, and we don't want bash to report an error)
|
||||||
if dpkg-query --show ${dep_app}-ynh-deps &>/dev/null
|
if dpkg-query --show ${dep_app}-ynh-deps &> /dev/null; then
|
||||||
then
|
|
||||||
ynh_package_autopurge ${dep_app}-ynh-deps
|
ynh_package_autopurge ${dep_app}-ynh-deps
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install packages from an extra repository properly.
|
# Install packages from an extra repository properly.
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_install_extra_app_dependencies --repo="repo" --package="dep1 dep2" [--key=key_url] [--name=name]
|
# 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: -r, --repo= - Complete url of the extra repository.
|
||||||
# | arg: -p, --package= - The packages to install from this extra repository
|
# | arg: -p, --package= - The packages to install from this extra repository
|
||||||
|
@ -476,21 +466,31 @@ ynh_install_extra_repo() {
|
||||||
wget_append="tee"
|
wget_append="tee"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Split the repository into uri, suite and components.
|
if [[ "$key" == "trusted=yes" ]]; then
|
||||||
|
trusted="--trusted"
|
||||||
|
else
|
||||||
|
trusted=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
IFS=', ' read -r -a repo_parts <<< "$repo"
|
||||||
|
index=0
|
||||||
|
|
||||||
# Remove "deb " at the beginning of the repo.
|
# Remove "deb " at the beginning of the repo.
|
||||||
repo="${repo#deb }"
|
if [[ "${repo_parts[0]}" == "deb" ]]; then
|
||||||
|
index=1
|
||||||
# Get the uri
|
fi
|
||||||
local uri="$(echo "$repo" | awk '{ print $1 }')"
|
uri="${repo_parts[$index]}"
|
||||||
|
index=$((index + 1))
|
||||||
# Get the suite
|
suite="${repo_parts[$index]}"
|
||||||
local suite="$(echo "$repo" | awk '{ print $2 }')"
|
index=$((index + 1))
|
||||||
|
|
||||||
# Get the components
|
# Get the components
|
||||||
local component="${repo##$uri $suite }"
|
if (("${#repo_parts[@]}" > 0)); then
|
||||||
|
component="${repo_parts[*]:$index}"
|
||||||
|
fi
|
||||||
|
|
||||||
# Add the repository into sources.list.d
|
# Add the repository into sources.list.d
|
||||||
ynh_add_repo --uri="$uri" --suite="$suite" --component="$component" --name="$name" $append
|
ynh_add_repo --uri="$uri" --suite="$suite" --component="$component" --name="$name" $append $trusted
|
||||||
|
|
||||||
# Pin the new repo with the default priority, so it won't be used for upgrades.
|
# Pin the new repo with the default priority, so it won't be used for upgrades.
|
||||||
# Build $pin from the uri without http and any sub path
|
# Build $pin from the uri without http and any sub path
|
||||||
|
@ -503,7 +503,7 @@ ynh_install_extra_repo() {
|
||||||
ynh_pin_repo --package="*" --pin="origin \"$pin\"" $priority --name="$name" $append
|
ynh_pin_repo --package="*" --pin="origin \"$pin\"" $priority --name="$name" $append
|
||||||
|
|
||||||
# Get the public key for the repo
|
# Get the public key for the repo
|
||||||
if [ -n "$key" ]; then
|
if [ -n "$key" ] && [[ "$key" != "trusted=yes" ]]; then
|
||||||
mkdir --parents "/etc/apt/trusted.gpg.d"
|
mkdir --parents "/etc/apt/trusted.gpg.d"
|
||||||
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
||||||
wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor | $wget_append /etc/apt/trusted.gpg.d/$name.gpg > /dev/null
|
wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor | $wget_append /etc/apt/trusted.gpg.d/$name.gpg > /dev/null
|
||||||
|
@ -556,6 +556,7 @@ ynh_remove_extra_repo() {
|
||||||
# | arg: -c, --component= - Component of the repository.
|
# | arg: -c, --component= - Component of the repository.
|
||||||
# | arg: -n, --name= - Name for the files for this repo, $app as default value.
|
# | arg: -n, --name= - Name for the files for this repo, $app as default value.
|
||||||
# | arg: -a, --append - Do not overwrite existing files.
|
# | arg: -a, --append - Do not overwrite existing files.
|
||||||
|
# | arg: -t, --trusted - Add trusted=yes to the repository (not recommended)
|
||||||
#
|
#
|
||||||
# Example for a repo like deb http://forge.yunohost.org/debian/ stretch stable
|
# Example for a repo like deb http://forge.yunohost.org/debian/ stretch stable
|
||||||
# uri suite component
|
# uri suite component
|
||||||
|
@ -564,27 +565,34 @@ ynh_remove_extra_repo() {
|
||||||
# Requires YunoHost version 3.8.1 or higher.
|
# Requires YunoHost version 3.8.1 or higher.
|
||||||
ynh_add_repo() {
|
ynh_add_repo() {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=uscna
|
local legacy_args=uscnat
|
||||||
local -A args_array=([u]=uri= [s]=suite= [c]=component= [n]=name= [a]=append)
|
local -A args_array=([u]=uri= [s]=suite= [c]=component= [n]=name= [a]=append [t]=trusted)
|
||||||
local uri
|
local uri
|
||||||
local suite
|
local suite
|
||||||
local component
|
local component
|
||||||
local name
|
local name
|
||||||
local append
|
local append
|
||||||
|
local trusted
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
name="${name:-$app}"
|
name="${name:-$app}"
|
||||||
append=${append:-0}
|
append=${append:-0}
|
||||||
|
trusted=${trusted:-0}
|
||||||
|
|
||||||
if [ $append -eq 1 ]; then
|
if [ $append -eq 1 ]; then
|
||||||
append="tee --append"
|
append="tee --append"
|
||||||
else
|
else
|
||||||
append="tee"
|
append="tee"
|
||||||
fi
|
fi
|
||||||
|
if [[ "$trusted" -eq 1 ]]; then
|
||||||
|
trust="[trusted=yes]"
|
||||||
|
else
|
||||||
|
trust=""
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir --parents "/etc/apt/sources.list.d"
|
mkdir --parents "/etc/apt/sources.list.d"
|
||||||
# Add the new repo in sources.list.d
|
# Add the new repo in sources.list.d
|
||||||
echo "deb $uri $suite $component" \
|
echo "deb $trust $uri $suite $component" \
|
||||||
| $append "/etc/apt/sources.list.d/$name.list"
|
| $append "/etc/apt/sources.list.d/$name.list"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -289,8 +289,7 @@ ynh_restore_file() {
|
||||||
# Boring hack for nginx conf file mapped to php7.3
|
# Boring hack for nginx conf file mapped to php7.3
|
||||||
# Note that there's no need to patch the fpm config because most php apps
|
# Note that there's no need to patch the fpm config because most php apps
|
||||||
# will call "ynh_add_fpm_config" during restore, effectively recreating the file from scratch
|
# will call "ynh_add_fpm_config" during restore, effectively recreating the file from scratch
|
||||||
if [[ "${dest_path}" == "/etc/nginx/conf.d/"* ]] && grep 'php7.3.*sock' "${dest_path}"
|
if [[ "${dest_path}" == "/etc/nginx/conf.d/"* ]] && grep 'php7.3.*sock' "${dest_path}"; then
|
||||||
then
|
|
||||||
sed -i 's/php7.3/php7.4/g' "${dest_path}"
|
sed -i 's/php7.3/php7.4/g' "${dest_path}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -376,8 +375,7 @@ ynh_backup_if_checksum_is_different() {
|
||||||
echo "$backup_file_checksum" # Return the name of the backup file
|
echo "$backup_file_checksum" # Return the name of the backup file
|
||||||
if [ ${PACKAGE_CHECK_EXEC:-0} -eq 1 ]; then
|
if [ ${PACKAGE_CHECK_EXEC:-0} -eq 1 ]; then
|
||||||
local file_path_base64=$(echo "$file" | base64 -w0)
|
local file_path_base64=$(echo "$file" | base64 -w0)
|
||||||
if test -e /var/cache/yunohost/appconfbackup/original_${file_path_base64}
|
if test -e /var/cache/yunohost/appconfbackup/original_${file_path_base64}; then
|
||||||
then
|
|
||||||
ynh_print_warn "Diff with the original file:"
|
ynh_print_warn "Diff with the original file:"
|
||||||
diff --report-identical-files --unified --color=always /var/cache/yunohost/appconfbackup/original_${file_path_base64} $file >&2 || true
|
diff --report-identical-files --unified --color=always /var/cache/yunohost/appconfbackup/original_${file_path_base64} $file >&2 || true
|
||||||
fi
|
fi
|
||||||
|
@ -494,8 +492,7 @@ ynh_restore_upgradebackup() {
|
||||||
yunohost app remove $app
|
yunohost app remove $app
|
||||||
# Restore the backup
|
# Restore the backup
|
||||||
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
|
||||||
if [[ -d /etc/yunohost/apps/$app ]]
|
if [[ -d /etc/yunohost/apps/$app ]]; then
|
||||||
then
|
|
||||||
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."
|
||||||
else
|
else
|
||||||
ynh_die --message="Uhoh ... Yunohost failed to restore the app to the way it was before the failed upgrade :|"
|
ynh_die --message="Uhoh ... Yunohost failed to restore the app to the way it was before the failed upgrade :|"
|
||||||
|
|
82
helpers/helpers.v1.d/composer
Normal file
82
helpers/helpers.v1.d/composer
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
readonly YNH_DEFAULT_COMPOSER_VERSION=1.10.17
|
||||||
|
# Declare the actual composer version to use.
|
||||||
|
# A packager willing to use another version of composer can override the variable into its _common.sh.
|
||||||
|
YNH_COMPOSER_VERSION=${YNH_COMPOSER_VERSION:-$YNH_DEFAULT_COMPOSER_VERSION}
|
||||||
|
|
||||||
|
# Execute a command with Composer
|
||||||
|
#
|
||||||
|
# usage: ynh_composer_exec [--phpversion=phpversion] [--workdir=$install_dir] --commands="commands"
|
||||||
|
# | arg: -v, --phpversion - PHP version to use with composer
|
||||||
|
# | arg: -w, --workdir - The directory from where the command will be executed. Default $install_dir or $final_path
|
||||||
|
# | arg: -c, --commands - Commands to execute.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 4.2 or higher.
|
||||||
|
ynh_composer_exec() {
|
||||||
|
local _globalphpversion=${phpversion-:}
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=vwc
|
||||||
|
declare -Ar args_array=([v]=phpversion= [w]=workdir= [c]=commands=)
|
||||||
|
local phpversion
|
||||||
|
local workdir
|
||||||
|
local commands
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
workdir="${workdir:-${install_dir:-$final_path}}"
|
||||||
|
|
||||||
|
if dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} lt 2; then
|
||||||
|
phpversion="${phpversion:-$YNH_PHP_VERSION}"
|
||||||
|
else
|
||||||
|
phpversion="${phpversion:-$_globalphpversion}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMPOSER_HOME="$workdir/.composer" COMPOSER_MEMORY_LIMIT=-1 \
|
||||||
|
php${phpversion} "$workdir/composer.phar" $commands \
|
||||||
|
-d "$workdir" --no-interaction --no-ansi 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install and initialize Composer in the given directory
|
||||||
|
#
|
||||||
|
# usage: ynh_install_composer [--phpversion=phpversion] [--workdir=$install_dir] [--install_args="--optimize-autoloader"] [--composerversion=composerversion]
|
||||||
|
# | arg: -v, --phpversion - PHP version to use with composer
|
||||||
|
# | arg: -w, --workdir - The directory from where the command will be executed. Default $install_dir.
|
||||||
|
# | arg: -a, --install_args - Additional arguments provided to the composer install. Argument --no-dev already include
|
||||||
|
# | arg: -c, --composerversion - Composer version to install
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 4.2 or higher.
|
||||||
|
ynh_install_composer() {
|
||||||
|
local _globalphpversion=${phpversion-:}
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=vwac
|
||||||
|
declare -Ar args_array=([v]=phpversion= [w]=workdir= [a]=install_args= [c]=composerversion=)
|
||||||
|
local phpversion
|
||||||
|
local workdir
|
||||||
|
local install_args
|
||||||
|
local composerversion
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
if dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} lt 2; then
|
||||||
|
workdir="${workdir:-$final_path}"
|
||||||
|
else
|
||||||
|
workdir="${workdir:-$install_dir}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} lt 2; then
|
||||||
|
phpversion="${phpversion:-$YNH_PHP_VERSION}"
|
||||||
|
else
|
||||||
|
phpversion="${phpversion:-$_globalphpversion}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
install_args="${install_args:-}"
|
||||||
|
composerversion="${composerversion:-$YNH_COMPOSER_VERSION}"
|
||||||
|
|
||||||
|
curl -sS https://getcomposer.org/installer \
|
||||||
|
| COMPOSER_HOME="$workdir/.composer" \
|
||||||
|
php${phpversion} -- --quiet --install-dir="$workdir" --version=$composerversion \
|
||||||
|
|| ynh_die --message="Unable to install Composer."
|
||||||
|
|
||||||
|
# install dependencies
|
||||||
|
ynh_composer_exec --phpversion="${phpversion}" --workdir="$workdir" --commands="install --no-dev $install_args" \
|
||||||
|
|| ynh_die --message="Unable to install core dependencies with Composer."
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ _ynh_app_config_get_one() {
|
||||||
if [[ "$bind" == "settings" ]]; then
|
if [[ "$bind" == "settings" ]]; then
|
||||||
ynh_die --message="File '${short_setting}' can't be stored in settings"
|
ynh_die --message="File '${short_setting}' can't be stored in settings"
|
||||||
fi
|
fi
|
||||||
old[$short_setting]="$(ls "$(echo $bind | sed s@__INSTALL_DIR__@$install_dir@ | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)" 2>/dev/null || echo YNH_NULL)"
|
old[$short_setting]="$(ls "$bind" 2> /dev/null || echo YNH_NULL)"
|
||||||
file_hash[$short_setting]="true"
|
file_hash[$short_setting]="true"
|
||||||
|
|
||||||
# Get multiline text from settings or from a full file
|
# Get multiline text from settings or from a full file
|
||||||
|
@ -32,7 +32,7 @@ _ynh_app_config_get_one() {
|
||||||
elif [[ "$bind" == *":"* ]]; then
|
elif [[ "$bind" == *":"* ]]; then
|
||||||
ynh_die --message="For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
|
ynh_die --message="For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
|
||||||
else
|
else
|
||||||
old[$short_setting]="$(cat $(echo $bind | sed s@__INSTALL_DIR__@$install_dir@ | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/) 2>/dev/null || echo YNH_NULL)"
|
old[$short_setting]="$(cat "$bind" 2> /dev/null || echo YNH_NULL)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get value from a kind of key/value file
|
# Get value from a kind of key/value file
|
||||||
|
@ -47,7 +47,7 @@ _ynh_app_config_get_one() {
|
||||||
bind_after="$(echo "${bind_key_}" | cut -d'>' -f1)"
|
bind_after="$(echo "${bind_key_}" | cut -d'>' -f1)"
|
||||||
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
||||||
fi
|
fi
|
||||||
local bind_file="$(echo "$bind" | cut -d: -f2 | sed s@__INSTALL_DIR__@$install_dir@ | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
|
local bind_file="$(echo "$bind" | cut -d: -f2)"
|
||||||
old[$short_setting]="$(ynh_read_var_in_file --file="${bind_file}" --key="${bind_key_}" --after="${bind_after}")"
|
old[$short_setting]="$(ynh_read_var_in_file --file="${bind_file}" --key="${bind_key_}" --after="${bind_after}")"
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
@ -73,7 +73,7 @@ _ynh_app_config_apply_one() {
|
||||||
if [[ "$bind" == "settings" ]]; then
|
if [[ "$bind" == "settings" ]]; then
|
||||||
ynh_die --message="File '${short_setting}' can't be stored in settings"
|
ynh_die --message="File '${short_setting}' can't be stored in settings"
|
||||||
fi
|
fi
|
||||||
local bind_file="$(echo "$bind" | sed s@__INSTALL_DIR__@$install_dir@ | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
|
local bind_file="$bind"
|
||||||
if [[ "${!short_setting}" == "" ]]; then
|
if [[ "${!short_setting}" == "" ]]; then
|
||||||
ynh_backup_if_checksum_is_different --file="$bind_file"
|
ynh_backup_if_checksum_is_different --file="$bind_file"
|
||||||
ynh_secure_remove --file="$bind_file"
|
ynh_secure_remove --file="$bind_file"
|
||||||
|
@ -98,7 +98,7 @@ _ynh_app_config_apply_one() {
|
||||||
if [[ "$bind" == *":"* ]]; then
|
if [[ "$bind" == *":"* ]]; then
|
||||||
ynh_die --message="For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
|
ynh_die --message="For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
|
||||||
fi
|
fi
|
||||||
local bind_file="$(echo "$bind" | sed s@__INSTALL_DIR__@$install_dir@ | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
|
local bind_file="$bind"
|
||||||
ynh_backup_if_checksum_is_different --file="$bind_file"
|
ynh_backup_if_checksum_is_different --file="$bind_file"
|
||||||
echo "${!short_setting}" > "$bind_file"
|
echo "${!short_setting}" > "$bind_file"
|
||||||
ynh_store_file_checksum --file="$bind_file" --update_only
|
ynh_store_file_checksum --file="$bind_file" --update_only
|
||||||
|
@ -113,7 +113,7 @@ _ynh_app_config_apply_one() {
|
||||||
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
||||||
fi
|
fi
|
||||||
bind_key_=${bind_key_:-$short_setting}
|
bind_key_=${bind_key_:-$short_setting}
|
||||||
local bind_file="$(echo "$bind" | cut -d: -f2 | sed s@__INSTALL_DIR__@$install_dir@ | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
|
local bind_file="$(echo "$bind" | cut -d: -f2)"
|
||||||
|
|
||||||
ynh_backup_if_checksum_is_different --file="$bind_file"
|
ynh_backup_if_checksum_is_different --file="$bind_file"
|
||||||
ynh_write_var_in_file --file="${bind_file}" --key="${bind_key_}" --value="${!short_setting}" --after="${bind_after}"
|
ynh_write_var_in_file --file="${bind_file}" --key="${bind_key_}" --value="${!short_setting}" --after="${bind_after}"
|
||||||
|
@ -126,60 +126,9 @@ _ynh_app_config_apply_one() {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_ynh_app_config_get() {
|
_ynh_app_config_get() {
|
||||||
# From settings
|
for line in $YNH_APP_CONFIG_PANEL_OPTIONS_TYPES_AND_BINDS; do
|
||||||
local lines
|
|
||||||
lines=$(
|
|
||||||
python3 <<EOL
|
|
||||||
import toml
|
|
||||||
from collections import OrderedDict
|
|
||||||
with open("../config_panel.toml", "r") as f:
|
|
||||||
file_content = f.read()
|
|
||||||
loaded_toml = toml.loads(file_content, _dict=OrderedDict)
|
|
||||||
|
|
||||||
for panel_name, panel in loaded_toml.items():
|
|
||||||
if not isinstance(panel, dict): continue
|
|
||||||
bind_panel = panel.get('bind')
|
|
||||||
for section_name, section in panel.items():
|
|
||||||
if not isinstance(section, dict): continue
|
|
||||||
bind_section = section.get('bind')
|
|
||||||
if not bind_section:
|
|
||||||
bind_section = bind_panel
|
|
||||||
elif bind_section[-1] == ":" and bind_panel and ":" in bind_panel:
|
|
||||||
regex, bind_panel_file = bind_panel.split(":")
|
|
||||||
if ">" in bind_section:
|
|
||||||
bind_section = bind_section + bind_panel_file
|
|
||||||
else:
|
|
||||||
bind_section = regex + bind_section + bind_panel_file
|
|
||||||
|
|
||||||
for name, param in section.items():
|
|
||||||
if not isinstance(param, dict):
|
|
||||||
continue
|
|
||||||
|
|
||||||
bind = param.get('bind')
|
|
||||||
|
|
||||||
if not bind:
|
|
||||||
if bind_section:
|
|
||||||
bind = bind_section
|
|
||||||
else:
|
|
||||||
bind = 'settings'
|
|
||||||
elif bind[-1] == ":" and bind_section and ":" in bind_section:
|
|
||||||
regex, bind_file = bind_section.split(":")
|
|
||||||
if ">" in bind:
|
|
||||||
bind = bind + bind_file
|
|
||||||
else:
|
|
||||||
bind = regex + bind + bind_file
|
|
||||||
if bind == "settings" and param.get('type', 'string') == 'file':
|
|
||||||
bind = 'null'
|
|
||||||
|
|
||||||
print('|'.join([
|
|
||||||
name,
|
|
||||||
param.get('type', 'string'),
|
|
||||||
bind
|
|
||||||
]))
|
|
||||||
EOL
|
|
||||||
)
|
|
||||||
for line in $lines; do
|
|
||||||
# Split line into short_setting, type and bind
|
# Split line into short_setting, type and bind
|
||||||
IFS='|' read short_setting type bind <<< "$line"
|
IFS='|' read short_setting type bind <<< "$line"
|
||||||
binds[${short_setting}]="$bind"
|
binds[${short_setting}]="$bind"
|
||||||
|
@ -188,7 +137,6 @@ EOL
|
||||||
formats[${short_setting}]=""
|
formats[${short_setting}]=""
|
||||||
ynh_app_config_get_one $short_setting $type $bind
|
ynh_app_config_get_one $short_setting $type $bind
|
||||||
done
|
done
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ynh_app_config_apply() {
|
_ynh_app_config_apply() {
|
||||||
|
@ -350,5 +298,6 @@ ynh_app_config_run() {
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
ynh_app_action_run $1
|
ynh_app_action_run $1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,7 @@
|
||||||
# ignoreregex =
|
# ignoreregex =
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
# -----------------------------------------------------------------------------
|
# ##### Note about the "failregex" option:
|
||||||
#
|
|
||||||
# Note about the "failregex" option:
|
|
||||||
#
|
#
|
||||||
# regex to match the password failure messages in the logfile. The host must be
|
# regex to match the password failure messages in the logfile. The host must be
|
||||||
# matched by a group named "`host`". The tag "`<HOST>`" can be used for standard
|
# matched by a group named "`host`". The tag "`<HOST>`" can be used for standard
|
||||||
|
|
|
@ -210,29 +210,24 @@ ynh_cleanup_go () {
|
||||||
# List required Go versions
|
# List required Go versions
|
||||||
local installed_apps=$(yunohost app list --output-as json --quiet | jq -r .apps[].id)
|
local installed_apps=$(yunohost app list --output-as json --quiet | jq -r .apps[].id)
|
||||||
local required_go_versions=""
|
local required_go_versions=""
|
||||||
for installed_app in $installed_apps
|
for installed_app in $installed_apps; do
|
||||||
do
|
|
||||||
local installed_app_go_version=$(ynh_app_setting_get --app=$installed_app --key="go_version")
|
local installed_app_go_version=$(ynh_app_setting_get --app=$installed_app --key="go_version")
|
||||||
if [[ $installed_app_go_version ]]
|
if [[ $installed_app_go_version ]]; then
|
||||||
then
|
|
||||||
required_go_versions="${installed_app_go_version}\n${required_go_versions}"
|
required_go_versions="${installed_app_go_version}\n${required_go_versions}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Remove no more needed Go versions
|
# Remove no more needed Go versions
|
||||||
local installed_go_versions=$(goenv versions --bare --skip-aliases | grep -Ev '/')
|
local installed_go_versions=$(goenv versions --bare --skip-aliases | grep -Ev '/')
|
||||||
for installed_go_version in $installed_go_versions
|
for installed_go_version in $installed_go_versions; do
|
||||||
do
|
if ! $(echo ${required_go_versions} | grep "${installed_go_version}" 1> /dev/null 2>&1); then
|
||||||
if ! `echo ${required_go_versions} | grep "${installed_go_version}" 1>/dev/null 2>&1`
|
|
||||||
then
|
|
||||||
ynh_print_info --message="Removing of Go-$installed_go_version"
|
ynh_print_info --message="Removing of Go-$installed_go_version"
|
||||||
$goenv_install_dir/bin/goenv uninstall --force "$installed_go_version"
|
$goenv_install_dir/bin/goenv uninstall --force "$installed_go_version"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# If none Go version is required
|
# If none Go version is required
|
||||||
if [[ ! $required_go_versions ]]
|
if [[ ! $required_go_versions ]]; then
|
||||||
then
|
|
||||||
# Remove goenv environment configuration
|
# Remove goenv environment configuration
|
||||||
ynh_print_info --message="Removing of goenv"
|
ynh_print_info --message="Removing of goenv"
|
||||||
ynh_secure_remove --file="$goenv_install_dir"
|
ynh_secure_remove --file="$goenv_install_dir"
|
||||||
|
|
|
@ -93,8 +93,7 @@ ynh_exec_err() {
|
||||||
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
||||||
# (because in the past eval was used) ...
|
# (because in the past eval was used) ...
|
||||||
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
||||||
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
|
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]; then
|
||||||
then
|
|
||||||
ynh_print_err --message="$(eval $@)"
|
ynh_print_err --message="$(eval $@)"
|
||||||
else
|
else
|
||||||
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
||||||
|
@ -114,8 +113,7 @@ ynh_exec_warn() {
|
||||||
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
||||||
# (because in the past eval was used) ...
|
# (because in the past eval was used) ...
|
||||||
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
||||||
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
|
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]; then
|
||||||
then
|
|
||||||
ynh_print_warn --message="$(eval $@)"
|
ynh_print_warn --message="$(eval $@)"
|
||||||
else
|
else
|
||||||
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
||||||
|
@ -135,8 +133,7 @@ ynh_exec_warn_less() {
|
||||||
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
||||||
# (because in the past eval was used) ...
|
# (because in the past eval was used) ...
|
||||||
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
||||||
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
|
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]; then
|
||||||
then
|
|
||||||
eval $@ 2>&1
|
eval $@ 2>&1
|
||||||
else
|
else
|
||||||
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
||||||
|
@ -156,8 +153,7 @@ ynh_exec_quiet() {
|
||||||
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
||||||
# (because in the past eval was used) ...
|
# (because in the past eval was used) ...
|
||||||
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
||||||
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
|
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]; then
|
||||||
then
|
|
||||||
eval $@ > /dev/null
|
eval $@ > /dev/null
|
||||||
else
|
else
|
||||||
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
||||||
|
@ -177,8 +173,7 @@ ynh_exec_fully_quiet() {
|
||||||
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
|
||||||
# (because in the past eval was used) ...
|
# (because in the past eval was used) ...
|
||||||
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
# we detect this by checking that there's no 2nd arg, and $1 contains a space
|
||||||
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
|
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]; then
|
||||||
then
|
|
||||||
eval $@ > /dev/null 2>&1
|
eval $@ > /dev/null 2>&1
|
||||||
else
|
else
|
||||||
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
|
||||||
|
|
|
@ -17,10 +17,8 @@ ynh_use_logrotate() {
|
||||||
# Stupid patch to ignore legacy --non-append and --nonappend
|
# Stupid patch to ignore legacy --non-append and --nonappend
|
||||||
# which was never properly understood and improperly used and kind of bullshit
|
# which was never properly understood and improperly used and kind of bullshit
|
||||||
local all_args=(${@})
|
local all_args=(${@})
|
||||||
for I in $(seq 0 $(($# - 1)))
|
for I in $(seq 0 $(($# - 1))); do
|
||||||
do
|
if [[ "${all_args[$I]}" == "--non-append" ]] || [[ "${all_args[$I]}" == "--nonappend" ]]; then
|
||||||
if [[ "${all_args[$I]}" == "--non-append" ]] || [[ "${all_args[$I]}" == "--nonappend" ]]
|
|
||||||
then
|
|
||||||
unset all_args[$I]
|
unset all_args[$I]
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@ -43,8 +41,7 @@ ynh_use_logrotate() {
|
||||||
fi
|
fi
|
||||||
set +o noglob
|
set +o noglob
|
||||||
|
|
||||||
for stuff in $logfile
|
for stuff in $logfile; do
|
||||||
do
|
|
||||||
mkdir --parents $(dirname "$stuff")
|
mkdir --parents $(dirname "$stuff")
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -76,8 +73,7 @@ $logfile {
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if [[ "$FIRST_CALL_TO_LOGROTATE" == "true" ]]
|
if [[ "$FIRST_CALL_TO_LOGROTATE" == "true" ]]; then
|
||||||
then
|
|
||||||
cat $tempconf > /etc/logrotate.d/$app
|
cat $tempconf > /etc/logrotate.d/$app
|
||||||
else
|
else
|
||||||
cat $tempconf >> /etc/logrotate.d/$app
|
cat $tempconf >> /etc/logrotate.d/$app
|
||||||
|
|
|
@ -39,19 +39,16 @@ ynh_mongo_exec() {
|
||||||
eval=${eval:-0}
|
eval=${eval:-0}
|
||||||
|
|
||||||
# If user is provided
|
# If user is provided
|
||||||
if [ -n "$user" ]
|
if [ -n "$user" ]; then
|
||||||
then
|
|
||||||
user="--username=$user"
|
user="--username=$user"
|
||||||
|
|
||||||
# If password is provided
|
# If password is provided
|
||||||
if [ -n "$password" ]
|
if [ -n "$password" ]; then
|
||||||
then
|
|
||||||
password="--password=$password"
|
password="--password=$password"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If authenticationdatabase is provided
|
# If authenticationdatabase is provided
|
||||||
if [ -n "$authenticationdatabase" ]
|
if [ -n "$authenticationdatabase" ]; then
|
||||||
then
|
|
||||||
authenticationdatabase="--authenticationDatabase=$authenticationdatabase"
|
authenticationdatabase="--authenticationDatabase=$authenticationdatabase"
|
||||||
else
|
else
|
||||||
authenticationdatabase="--authenticationDatabase=admin"
|
authenticationdatabase="--authenticationDatabase=admin"
|
||||||
|
@ -62,23 +59,19 @@ ynh_mongo_exec() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If host is provided
|
# If host is provided
|
||||||
if [ -n "$host" ]
|
if [ -n "$host" ]; then
|
||||||
then
|
|
||||||
host="--host=$host"
|
host="--host=$host"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If port is provided
|
# If port is provided
|
||||||
if [ -n "$port" ]
|
if [ -n "$port" ]; then
|
||||||
then
|
|
||||||
port="--port=$port"
|
port="--port=$port"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If eval is not provided
|
# If eval is not provided
|
||||||
if [ $eval -eq 0 ]
|
if [ $eval -eq 0 ]; then
|
||||||
then
|
|
||||||
# If database is provided
|
# If database is provided
|
||||||
if [ -n "$database" ]
|
if [ -n "$database" ]; then
|
||||||
then
|
|
||||||
database="use $database"
|
database="use $database"
|
||||||
else
|
else
|
||||||
database=""
|
database=""
|
||||||
|
@ -91,8 +84,7 @@ quit()
|
||||||
EOF
|
EOF
|
||||||
else
|
else
|
||||||
# If database is provided
|
# If database is provided
|
||||||
if [ -n "$database" ]
|
if [ -n "$database" ]; then
|
||||||
then
|
|
||||||
database="$database"
|
database="$database"
|
||||||
else
|
else
|
||||||
database=""
|
database=""
|
||||||
|
@ -186,8 +178,7 @@ ynh_mongo_database_exists() {
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
if [ $(ynh_mongo_exec --command='db.getMongo().getDBNames().indexOf("'${database}'")' --eval) -lt 0 ]
|
if [ $(ynh_mongo_exec --command='db.getMongo().getDBNames().indexOf("'${database}'")' --eval) -lt 0 ]; then
|
||||||
then
|
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
|
@ -310,7 +301,7 @@ ynh_install_mongo() {
|
||||||
ynh_print_info --message="Installing MongoDB Community Edition ..."
|
ynh_print_info --message="Installing MongoDB Community Edition ..."
|
||||||
local mongo_debian_release=$(ynh_get_debian_release)
|
local mongo_debian_release=$(ynh_get_debian_release)
|
||||||
|
|
||||||
if [[ $(cat /proc/cpuinfo) != *"avx"* && "$mongo_version" != "4.4" ]]; then
|
if [[ "$(grep '^flags' /proc/cpuinfo | uniq)" != *"avx"* && "$mongo_version" != "4.4" ]]; then
|
||||||
ynh_print_warn --message="Installing Mongo 4.4 as $mongo_version is not compatible with your cpu (see https://docs.mongodb.com/manual/administration/production-notes/#x86_64)."
|
ynh_print_warn --message="Installing Mongo 4.4 as $mongo_version is not compatible with your cpu (see https://docs.mongodb.com/manual/administration/production-notes/#x86_64)."
|
||||||
mongo_version="4.4"
|
mongo_version="4.4"
|
||||||
fi
|
fi
|
||||||
|
@ -343,8 +334,7 @@ ynh_install_mongo() {
|
||||||
#
|
#
|
||||||
ynh_remove_mongo() {
|
ynh_remove_mongo() {
|
||||||
# Only remove the mongodb service if it is not installed.
|
# Only remove the mongodb service if it is not installed.
|
||||||
if ! ynh_package_is_installed --package="mongodb*"
|
if ! ynh_package_is_installed --package="mongodb*"; then
|
||||||
then
|
|
||||||
ynh_print_info --message="Removing MongoDB service..."
|
ynh_print_info --message="Removing MongoDB service..."
|
||||||
mongodb_servicename=mongod
|
mongodb_servicename=mongod
|
||||||
# Remove the mongodb service
|
# Remove the mongodb service
|
||||||
|
|
|
@ -43,7 +43,6 @@ ynh_remove_nginx_config() {
|
||||||
ynh_systemd_action --service_name=nginx --action=reload
|
ynh_systemd_action --service_name=nginx --action=reload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Regen the nginx config in a change url context
|
# Regen the nginx config in a change url context
|
||||||
#
|
#
|
||||||
# usage: ynh_change_url_nginx_config
|
# usage: ynh_change_url_nginx_config
|
||||||
|
|
|
@ -36,8 +36,6 @@
|
||||||
# | arg: -t, --show_tile= - (optional) Define if a tile will be shown in the SSO. If yes the name of the tile will be the 'label' parameter. Defaults to false for the permission different than 'main'.
|
# | arg: -t, --show_tile= - (optional) Define if a tile will be shown in the SSO. If yes the name of the tile will be the 'label' parameter. Defaults to false for the permission different than 'main'.
|
||||||
# | arg: -P, --protected= - (optional) Define if this permission is protected. If it is protected the administrator won't be able to add or remove the visitors group of this permission. Defaults to 'false'.
|
# | arg: -P, --protected= - (optional) Define if this permission is protected. If it is protected the administrator won't be able to add or remove the visitors group of this permission. Defaults to 'false'.
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# If provided, 'url' or 'additional_urls' is assumed to be relative to the app domain/path if they
|
# If provided, 'url' or 'additional_urls' is assumed to be relative to the app domain/path if they
|
||||||
# start with '/'. For example:
|
# start with '/'. For example:
|
||||||
# / -> domain.tld/app
|
# / -> domain.tld/app
|
||||||
|
@ -145,8 +143,6 @@ ynh_permission_create() {
|
||||||
|
|
||||||
# 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)
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# example: ynh_permission_delete --permission=editors
|
# example: ynh_permission_delete --permission=editors
|
||||||
#
|
#
|
||||||
# usage: ynh_permission_delete --permission="permission"
|
# usage: ynh_permission_delete --permission="permission"
|
||||||
|
@ -165,8 +161,6 @@ ynh_permission_delete() {
|
||||||
|
|
||||||
# Check if a permission exists
|
# Check if a permission exists
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_permission_exists --permission=permission
|
# usage: ynh_permission_exists --permission=permission
|
||||||
# | arg: -p, --permission= - the permission to check
|
# | arg: -p, --permission= - the permission to check
|
||||||
# | exit: Return 1 if the permission doesn't exist, 0 otherwise
|
# | exit: Return 1 if the permission doesn't exist, 0 otherwise
|
||||||
|
@ -185,8 +179,6 @@ ynh_permission_exists() {
|
||||||
|
|
||||||
# Redefine the url associated to a permission
|
# Redefine the url associated to a permission
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_permission_url --permission "permission" [--url="url"] [--add_url="new-url" [ "other-new-url" ]] [--remove_url="old-url" [ "other-old-url" ]]
|
# usage: ynh_permission_url --permission "permission" [--url="url"] [--add_url="new-url" [ "other-new-url" ]] [--remove_url="old-url" [ "other-old-url" ]]
|
||||||
# [--auth_header=true|false] [--clear_urls]
|
# [--auth_header=true|false] [--clear_urls]
|
||||||
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed)
|
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed)
|
||||||
|
@ -255,8 +247,6 @@ ynh_permission_url() {
|
||||||
|
|
||||||
# Update a permission for the app
|
# Update a permission for the app
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]]
|
# usage: ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]]
|
||||||
# [--label="label"] [--show_tile=true|false] [--protected=true|false]
|
# [--label="label"] [--show_tile=true|false] [--protected=true|false]
|
||||||
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist)
|
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist)
|
||||||
|
@ -362,8 +352,6 @@ ynh_permission_has_user() {
|
||||||
|
|
||||||
# Check if a legacy permissions exist
|
# Check if a legacy permissions exist
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_legacy_permissions_exists
|
# usage: ynh_legacy_permissions_exists
|
||||||
# | exit: Return 1 if the permission doesn't exist, 0 otherwise
|
# | exit: Return 1 if the permission doesn't exist, 0 otherwise
|
||||||
#
|
#
|
||||||
|
@ -379,8 +367,6 @@ ynh_legacy_permissions_exists() {
|
||||||
|
|
||||||
# Remove all legacy permissions
|
# Remove all legacy permissions
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_legacy_permissions_delete_all
|
# usage: ynh_legacy_permissions_delete_all
|
||||||
#
|
#
|
||||||
# example:
|
# example:
|
||||||
|
|
|
@ -92,16 +92,14 @@ ynh_add_fpm_config() {
|
||||||
|
|
||||||
# If no usage provided, default to the value existing in setting ... or to low
|
# If no usage provided, default to the value existing in setting ... or to low
|
||||||
local fpm_usage_in_setting=$(ynh_app_setting_get --app=$app --key=fpm_usage)
|
local fpm_usage_in_setting=$(ynh_app_setting_get --app=$app --key=fpm_usage)
|
||||||
if [ -z "$usage" ]
|
if [ -z "$usage" ]; then
|
||||||
then
|
|
||||||
usage=${fpm_usage_in_setting:-low}
|
usage=${fpm_usage_in_setting:-low}
|
||||||
ynh_app_setting_set --app=$app --key=fpm_usage --value=$usage
|
ynh_app_setting_set --app=$app --key=fpm_usage --value=$usage
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If no footprint provided, default to the value existing in setting ... or to low
|
# If no footprint provided, default to the value existing in setting ... or to low
|
||||||
local fpm_footprint_in_setting=$(ynh_app_setting_get --app=$app --key=fpm_footprint)
|
local fpm_footprint_in_setting=$(ynh_app_setting_get --app=$app --key=fpm_footprint)
|
||||||
if [ -z "$footprint" ]
|
if [ -z "$footprint" ]; then
|
||||||
then
|
|
||||||
footprint=${fpm_footprint_in_setting:-low}
|
footprint=${fpm_footprint_in_setting:-low}
|
||||||
ynh_app_setting_set --app=$app --key=fpm_footprint --value=$footprint
|
ynh_app_setting_set --app=$app --key=fpm_footprint --value=$footprint
|
||||||
fi
|
fi
|
||||||
|
@ -125,8 +123,7 @@ ynh_add_fpm_config() {
|
||||||
local old_php_fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir)
|
local old_php_fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir)
|
||||||
local old_php_finalphpconf="$old_php_fpm_config_dir/pool.d/$app.conf"
|
local old_php_finalphpconf="$old_php_fpm_config_dir/pool.d/$app.conf"
|
||||||
|
|
||||||
if [[ -f "$old_php_finalphpconf" ]]
|
if [[ -f "$old_php_finalphpconf" ]]; then
|
||||||
then
|
|
||||||
ynh_backup_if_checksum_is_different --file="$old_php_finalphpconf"
|
ynh_backup_if_checksum_is_different --file="$old_php_finalphpconf"
|
||||||
ynh_remove_fpm_config
|
ynh_remove_fpm_config
|
||||||
fi
|
fi
|
||||||
|
@ -500,84 +497,3 @@ ynh_get_scalable_phpfpm() {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly YNH_DEFAULT_COMPOSER_VERSION=1.10.17
|
|
||||||
# Declare the actual composer version to use.
|
|
||||||
# A packager willing to use another version of composer can override the variable into its _common.sh.
|
|
||||||
YNH_COMPOSER_VERSION=${YNH_COMPOSER_VERSION:-$YNH_DEFAULT_COMPOSER_VERSION}
|
|
||||||
|
|
||||||
# Execute a command with Composer
|
|
||||||
#
|
|
||||||
# usage: ynh_composer_exec [--phpversion=phpversion] [--workdir=$install_dir] --commands="commands"
|
|
||||||
# | arg: -v, --phpversion - PHP version to use with composer
|
|
||||||
# | arg: -w, --workdir - The directory from where the command will be executed. Default $install_dir or $final_path
|
|
||||||
# | arg: -c, --commands - Commands to execute.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.2 or higher.
|
|
||||||
ynh_composer_exec() {
|
|
||||||
local _globalphpversion=${phpversion-:}
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=vwc
|
|
||||||
declare -Ar args_array=([v]=phpversion= [w]=workdir= [c]=commands=)
|
|
||||||
local phpversion
|
|
||||||
local workdir
|
|
||||||
local commands
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
workdir="${workdir:-${install_dir:-$final_path}}"
|
|
||||||
|
|
||||||
if dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} lt 2; then
|
|
||||||
phpversion="${phpversion:-$YNH_PHP_VERSION}"
|
|
||||||
else
|
|
||||||
phpversion="${phpversion:-$_globalphpversion}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
COMPOSER_HOME="$workdir/.composer" COMPOSER_MEMORY_LIMIT=-1 \
|
|
||||||
php${phpversion} "$workdir/composer.phar" $commands \
|
|
||||||
-d "$workdir" --no-interaction --no-ansi 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Install and initialize Composer in the given directory
|
|
||||||
#
|
|
||||||
# usage: ynh_install_composer [--phpversion=phpversion] [--workdir=$install_dir] [--install_args="--optimize-autoloader"] [--composerversion=composerversion]
|
|
||||||
# | arg: -v, --phpversion - PHP version to use with composer
|
|
||||||
# | arg: -w, --workdir - The directory from where the command will be executed. Default $install_dir.
|
|
||||||
# | arg: -a, --install_args - Additional arguments provided to the composer install. Argument --no-dev already include
|
|
||||||
# | arg: -c, --composerversion - Composer version to install
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.2 or higher.
|
|
||||||
ynh_install_composer() {
|
|
||||||
local _globalphpversion=${phpversion-:}
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=vwac
|
|
||||||
declare -Ar args_array=([v]=phpversion= [w]=workdir= [a]=install_args= [c]=composerversion=)
|
|
||||||
local phpversion
|
|
||||||
local workdir
|
|
||||||
local install_args
|
|
||||||
local composerversion
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
if dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} lt 2; then
|
|
||||||
workdir="${workdir:-$final_path}"
|
|
||||||
else
|
|
||||||
workdir="${workdir:-$install_dir}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} lt 2; then
|
|
||||||
phpversion="${phpversion:-$YNH_PHP_VERSION}"
|
|
||||||
else
|
|
||||||
phpversion="${phpversion:-$_globalphpversion}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
install_args="${install_args:-}"
|
|
||||||
composerversion="${composerversion:-$YNH_COMPOSER_VERSION}"
|
|
||||||
|
|
||||||
curl -sS https://getcomposer.org/installer \
|
|
||||||
| COMPOSER_HOME="$workdir/.composer" \
|
|
||||||
php${phpversion} -- --quiet --install-dir="$workdir" --version=$composerversion \
|
|
||||||
|| ynh_die --message="Unable to install Composer."
|
|
||||||
|
|
||||||
# install dependencies
|
|
||||||
ynh_composer_exec --phpversion="${phpversion}" --workdir="$workdir" --commands="install --no-dev $install_args" \
|
|
||||||
|| ynh_die --message="Unable to install core dependencies with Composer."
|
|
||||||
}
|
|
||||||
|
|
|
@ -199,8 +199,7 @@ ynh_psql_database_exists() {
|
||||||
|
|
||||||
# if psql is not there, we cannot check the db
|
# if psql is not there, we cannot check the db
|
||||||
# though it could exists.
|
# though it could exists.
|
||||||
if ! command -v psql
|
if ! command -v psql; then
|
||||||
then
|
|
||||||
ynh_print_err -m "PostgreSQL is not installed, impossible to check for db existence."
|
ynh_print_err -m "PostgreSQL is not installed, impossible to check for db existence."
|
||||||
return 1
|
return 1
|
||||||
elif ! 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"; then
|
elif ! 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"; then
|
||||||
|
|
|
@ -13,10 +13,8 @@ ynh_redis_get_free_db() {
|
||||||
|
|
||||||
db=0
|
db=0
|
||||||
# default Debian setting is 15 databases
|
# default Debian setting is 15 databases
|
||||||
for i in $(seq 0 "$max")
|
for i in $(seq 0 "$max"); do
|
||||||
do
|
if ! echo "$result" | grep -q "db$i"; then
|
||||||
if ! echo "$result" | grep -q "db$i"
|
|
||||||
then
|
|
||||||
db=$i
|
db=$i
|
||||||
break 1
|
break 1
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -210,8 +210,7 @@ ynh_install_ruby () {
|
||||||
ynh_app_setting_set --app=$app --key=ruby_version --value=$final_ruby_version
|
ynh_app_setting_set --app=$app --key=ruby_version --value=$final_ruby_version
|
||||||
|
|
||||||
# Remove app virtualenv
|
# Remove app virtualenv
|
||||||
if rbenv alias --list | grep --quiet "$app "
|
if rbenv alias --list | grep --quiet "$app "; then
|
||||||
then
|
|
||||||
rbenv alias $app --remove
|
rbenv alias $app --remove
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -267,29 +266,24 @@ ynh_cleanup_ruby () {
|
||||||
# List required Ruby versions
|
# List required Ruby versions
|
||||||
local installed_apps=$(yunohost app list | grep -oP 'id: \K.*$')
|
local installed_apps=$(yunohost app list | grep -oP 'id: \K.*$')
|
||||||
local required_ruby_versions=""
|
local required_ruby_versions=""
|
||||||
for installed_app in $installed_apps
|
for installed_app in $installed_apps; do
|
||||||
do
|
|
||||||
local installed_app_ruby_version=$(ynh_app_setting_get --app=$installed_app --key="ruby_version")
|
local installed_app_ruby_version=$(ynh_app_setting_get --app=$installed_app --key="ruby_version")
|
||||||
if [[ -n "$installed_app_ruby_version" ]]
|
if [[ -n "$installed_app_ruby_version" ]]; then
|
||||||
then
|
|
||||||
required_ruby_versions="${installed_app_ruby_version}\n${required_ruby_versions}"
|
required_ruby_versions="${installed_app_ruby_version}\n${required_ruby_versions}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Remove no more needed Ruby versions
|
# Remove no more needed Ruby versions
|
||||||
local installed_ruby_versions=$(rbenv versions --bare --skip-aliases | grep -Ev '/')
|
local installed_ruby_versions=$(rbenv versions --bare --skip-aliases | grep -Ev '/')
|
||||||
for installed_ruby_version in $installed_ruby_versions
|
for installed_ruby_version in $installed_ruby_versions; do
|
||||||
do
|
if ! echo ${required_ruby_versions} | grep -q "${installed_ruby_version}"; then
|
||||||
if ! echo ${required_ruby_versions} | grep -q "${installed_ruby_version}"
|
|
||||||
then
|
|
||||||
ynh_print_info --message="Removing Ruby-$installed_ruby_version"
|
ynh_print_info --message="Removing Ruby-$installed_ruby_version"
|
||||||
$rbenv_install_dir/bin/rbenv uninstall --force $installed_ruby_version
|
$rbenv_install_dir/bin/rbenv uninstall --force $installed_ruby_version
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# If none Ruby version is required
|
# If none Ruby version is required
|
||||||
if [[ -z "$required_ruby_versions" ]]
|
if [[ -z "$required_ruby_versions" ]]; then
|
||||||
then
|
|
||||||
# Remove rbenv environment configuration
|
# Remove rbenv environment configuration
|
||||||
ynh_print_info --message="Removing rbenv"
|
ynh_print_info --message="Removing rbenv"
|
||||||
ynh_secure_remove --file="$rbenv_install_dir"
|
ynh_secure_remove --file="$rbenv_install_dir"
|
||||||
|
|
|
@ -52,6 +52,42 @@ ynh_app_setting_set() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Set an application setting but only if the "$key" variable ain't set yet
|
||||||
|
#
|
||||||
|
# Note that it doesn't just define the setting but ALSO define the $foobar variable
|
||||||
|
#
|
||||||
|
# Hence it's meant as a replacement for this legacy overly complex syntax:
|
||||||
|
#
|
||||||
|
# if [ -z "${foo:-}" ]
|
||||||
|
# then
|
||||||
|
# foo="bar"
|
||||||
|
# ynh_app_setting_set --key="foo" --value="$foo"
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# usage: ynh_app_setting_set_default --app=app --key=key --value=value
|
||||||
|
# | arg: -a, --app= - the application id
|
||||||
|
# | arg: -k, --key= - the setting name to set
|
||||||
|
# | arg: -v, --value= - the default setting value to set
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 11.1.16 or higher.
|
||||||
|
ynh_app_setting_set_default() {
|
||||||
|
local _globalapp=${app-:}
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=akv
|
||||||
|
local -A args_array=([a]=app= [k]=key= [v]=value=)
|
||||||
|
local app
|
||||||
|
local key
|
||||||
|
local value
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
app="${app:-$_globalapp}"
|
||||||
|
|
||||||
|
if [ -z "${!key:-}" ]; then
|
||||||
|
eval $key=\$value
|
||||||
|
ynh_app_setting "set" "$app" "$key" "$value"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# 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
|
||||||
|
|
286
helpers/helpers.v1.d/sources
Normal file
286
helpers/helpers.v1.d/sources
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Download, check integrity, uncompress and patch the source from app.src
|
||||||
|
#
|
||||||
|
# usage: ynh_setup_source --dest_dir=dest_dir [--source_id=source_id] [--keep="file1 file2"] [--full_replace]
|
||||||
|
# | arg: -d, --dest_dir= - Directory where to setup sources
|
||||||
|
# | arg: -s, --source_id= - Name of the source, defaults to `main` (when the sources resource exists in manifest.toml) or (legacy) `app` otherwise
|
||||||
|
# | arg: -k, --keep= - Space-separated list of files/folders that will be backup/restored in $dest_dir, such as a config file you don't want to overwrite. For example 'conf.json secrets.json logs' (no trailing `/` for folders)
|
||||||
|
# | arg: -r, --full_replace= - Remove previous sources before installing new sources (can be 1 or 0, default to 0)
|
||||||
|
#
|
||||||
|
# ##### New 'sources' resources
|
||||||
|
#
|
||||||
|
# (See also the resources documentation which may be more complete?)
|
||||||
|
#
|
||||||
|
# This helper will read infos from the 'sources' resources in the manifest.toml of the app
|
||||||
|
# and expect a structure like:
|
||||||
|
#
|
||||||
|
# ```toml
|
||||||
|
# [resources.sources]
|
||||||
|
# [resources.sources.main]
|
||||||
|
# url = "https://some.address.to/download/the/app/archive"
|
||||||
|
# sha256 = "0123456789abcdef" # The sha256 sum of the asset obtained from the URL
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# ##### Optional flags
|
||||||
|
#
|
||||||
|
# ```text
|
||||||
|
# format = "tar.gz"/xz/bz2 # automatically guessed from the extension of the URL, but can be set explicitly. Will use `tar` to extract
|
||||||
|
# "zip" # automatically guessed from the extension of the URL, but can be set explicitly. Will use `unzip` to extract
|
||||||
|
# "docker" # useful to extract files from an already-built docker image (instead of rebuilding them locally). Will use `docker-image-extract` to extract
|
||||||
|
# "whatever" # an arbitrary value, not really meaningful except to imply that the file won't be extracted
|
||||||
|
#
|
||||||
|
# in_subdir = true # default, there's an intermediate subdir in the archive before accessing the actual files
|
||||||
|
# false # sources are directly in the archive root
|
||||||
|
# n # (special cases) an integer representing a number of subdirs levels to get rid of
|
||||||
|
#
|
||||||
|
# extract = true # default if file is indeed an archive such as .zip, .tar.gz, .tar.bz2, ...
|
||||||
|
# = false # default if file 'format' is not set and the file is not to be extracted because it is not an archive but a script or binary or whatever asset.
|
||||||
|
# # in which case the file will only be `mv`ed to the location possibly renamed using the `rename` value
|
||||||
|
#
|
||||||
|
# rename = "whatever_your_want" # to be used for convenience when `extract` is false and the default name of the file is not practical
|
||||||
|
# platform = "linux/amd64" # (defaults to "linux/$YNH_ARCH") to be used in conjonction with `format = "docker"` to specify which architecture to extract for
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# You may also define assets url and checksum per-architectures such as:
|
||||||
|
# ```toml
|
||||||
|
# [resources.sources]
|
||||||
|
# [resources.sources.main]
|
||||||
|
# amd64.url = "https://some.address.to/download/the/app/archive/when/amd64"
|
||||||
|
# amd64.sha256 = "0123456789abcdef"
|
||||||
|
# armhf.url = "https://some.address.to/download/the/app/archive/when/armhf"
|
||||||
|
# armhf.sha256 = "fedcba9876543210"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# In which case `ynh_setup_source --dest_dir="$install_dir"` will automatically pick the appropriate source depending on the arch
|
||||||
|
#
|
||||||
|
# The helper will:
|
||||||
|
# - Download the specific URL if there is no local archive
|
||||||
|
# - Check the integrity with the specific sha256 sum
|
||||||
|
# - Uncompress the archive to `$dest_dir`.
|
||||||
|
# - If `in_subdir` is true, the first level directory of the archive will be removed.
|
||||||
|
# - If `in_subdir` is a numeric value, the N first level directories will be removed.
|
||||||
|
# - Patches named `sources/patches/${src_id}-*.patch` will be applied to `$dest_dir`
|
||||||
|
# - Extra files in `sources/extra_files/$src_id` will be copied to dest_dir
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
ynh_setup_source() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=dsk
|
||||||
|
local -A args_array=([d]=dest_dir= [s]=source_id= [k]=keep= [r]=full_replace=)
|
||||||
|
local dest_dir
|
||||||
|
local source_id
|
||||||
|
local keep
|
||||||
|
local full_replace
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
keep="${keep:-}"
|
||||||
|
full_replace="${full_replace:-0}"
|
||||||
|
|
||||||
|
if test -e $YNH_APP_BASEDIR/manifest.toml && cat $YNH_APP_BASEDIR/manifest.toml | toml_to_json | jq -e '.resources.sources' > /dev/null; then
|
||||||
|
source_id="${source_id:-main}"
|
||||||
|
local sources_json=$(cat $YNH_APP_BASEDIR/manifest.toml | toml_to_json | jq ".resources.sources[\"$source_id\"]")
|
||||||
|
if jq -re ".url" <<< "$sources_json"; then
|
||||||
|
local arch_prefix=""
|
||||||
|
else
|
||||||
|
local arch_prefix=".$YNH_ARCH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local src_url="$(jq -r "$arch_prefix.url" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_sum="$(jq -r "$arch_prefix.sha256" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_sumprg="sha256sum"
|
||||||
|
local src_format="$(jq -r ".format" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_in_subdir="$(jq -r ".in_subdir" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_extract="$(jq -r ".extract" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_platform="$(jq -r ".platform" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_rename="$(jq -r ".rename" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
|
||||||
|
[[ -n "$src_url" ]] || ynh_die "No URL defined for source $source_id$arch_prefix ?"
|
||||||
|
[[ -n "$src_sum" ]] || ynh_die "No sha256 sum defined for source $source_id$arch_prefix ?"
|
||||||
|
|
||||||
|
if [[ -z "$src_format" ]]; then
|
||||||
|
if [[ "$src_url" =~ ^.*\.zip$ ]] || [[ "$src_url" =~ ^.*/zipball/.*$ ]]; then
|
||||||
|
src_format="zip"
|
||||||
|
elif [[ "$src_url" =~ ^.*\.tar\.gz$ ]] || [[ "$src_url" =~ ^.*\.tgz$ ]] || [[ "$src_url" =~ ^.*/tar\.gz/.*$ ]] || [[ "$src_url" =~ ^.*/tarball/.*$ ]]; then
|
||||||
|
src_format="tar.gz"
|
||||||
|
elif [[ "$src_url" =~ ^.*\.tar\.xz$ ]]; then
|
||||||
|
src_format="tar.xz"
|
||||||
|
elif [[ "$src_url" =~ ^.*\.tar\.bz2$ ]]; then
|
||||||
|
src_format="tar.bz2"
|
||||||
|
elif [[ -z "$src_extract" ]]; then
|
||||||
|
src_extract="false"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
source_id="${source_id:-app}"
|
||||||
|
local src_file_path="$YNH_APP_BASEDIR/conf/${source_id}.src"
|
||||||
|
|
||||||
|
# Load value from configuration file (see above for a small doc about this file
|
||||||
|
# format)
|
||||||
|
local src_url=$(grep 'SOURCE_URL=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
|
local src_sum=$(grep 'SOURCE_SUM=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
|
local src_sumprg=$(grep 'SOURCE_SUM_PRG=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
|
local src_format=$(grep 'SOURCE_FORMAT=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
|
local src_in_subdir=$(grep 'SOURCE_IN_SUBDIR=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
|
local src_rename=$(grep 'SOURCE_FILENAME=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
|
local src_extract=$(grep 'SOURCE_EXTRACT=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
|
local src_platform=$(grep 'SOURCE_PLATFORM=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Default value
|
||||||
|
src_sumprg=${src_sumprg:-sha256sum}
|
||||||
|
src_in_subdir=${src_in_subdir:-true}
|
||||||
|
src_format=${src_format:-tar.gz}
|
||||||
|
src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]')
|
||||||
|
src_extract=${src_extract:-true}
|
||||||
|
|
||||||
|
if [[ "$src_extract" != "true" ]] && [[ "$src_extract" != "false" ]]; then
|
||||||
|
ynh_die "For source $source_id, expected either 'true' or 'false' for the extract parameter"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# (Unused?) mecanism where one can have the file in a special local cache to not have to download it...
|
||||||
|
local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${source_id}"
|
||||||
|
|
||||||
|
# Gotta use this trick with 'dirname' because source_id may contain slashes x_x
|
||||||
|
mkdir -p $(dirname /var/cache/yunohost/download/${YNH_APP_ID}/${source_id})
|
||||||
|
src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${source_id}"
|
||||||
|
|
||||||
|
if [ "$src_format" = "docker" ]; then
|
||||||
|
src_platform="${src_platform:-"linux/$YNH_ARCH"}"
|
||||||
|
else
|
||||||
|
if test -e "$local_src"; then
|
||||||
|
cp $local_src $src_filename
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?"
|
||||||
|
|
||||||
|
# If the file was prefetched but somehow doesn't match the sum, rm and redownload it
|
||||||
|
if [ -e "$src_filename" ] && ! echo "${src_sum} ${src_filename}" | ${src_sumprg} --check --status; then
|
||||||
|
rm -f "$src_filename"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Only redownload the file if it wasnt prefetched
|
||||||
|
if [ ! -e "$src_filename" ]; then
|
||||||
|
# NB. we have to declare the var as local first,
|
||||||
|
# otherwise 'local foo=$(false) || echo 'pwet'" does'nt work
|
||||||
|
# because local always return 0 ...
|
||||||
|
local out
|
||||||
|
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
||||||
|
out=$(wget --tries 3 --no-dns-cache --timeout 900 --no-verbose --output-document=$src_filename $src_url 2>&1) \
|
||||||
|
|| ynh_die --message="$out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check the control sum
|
||||||
|
if ! echo "${src_sum} ${src_filename}" | ${src_sumprg} --check --status; then
|
||||||
|
local actual_sum="$(${src_sumprg} ${src_filename} | cut --delimiter=' ' --fields=1)"
|
||||||
|
local actual_size="$(du -hs ${src_filename} | cut --fields=1)"
|
||||||
|
rm -f ${src_filename}
|
||||||
|
ynh_die --message="Corrupt source for ${src_url}: Expected sha256sum to be ${src_sum} but got ${actual_sum} (size: ${actual_size})."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Keep files to be backup/restored at the end of the helper
|
||||||
|
# Assuming $dest_dir already exists
|
||||||
|
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
||||||
|
if [ -n "$keep" ] && [ -e "$dest_dir" ]; then
|
||||||
|
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
||||||
|
mkdir -p $keep_dir
|
||||||
|
local stuff_to_keep
|
||||||
|
for stuff_to_keep in $keep; do
|
||||||
|
if [ -e "$dest_dir/$stuff_to_keep" ]; then
|
||||||
|
mkdir --parents "$(dirname "$keep_dir/$stuff_to_keep")"
|
||||||
|
cp --archive "$dest_dir/$stuff_to_keep" "$keep_dir/$stuff_to_keep"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$full_replace" -eq 1 ]; then
|
||||||
|
ynh_secure_remove --file="$dest_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract source into the app dir
|
||||||
|
mkdir --parents "$dest_dir"
|
||||||
|
|
||||||
|
if [ -n "${install_dir:-}" ] && [ "$dest_dir" == "$install_dir" ]; then
|
||||||
|
_ynh_apply_default_permissions $dest_dir
|
||||||
|
fi
|
||||||
|
if [ -n "${final_path:-}" ] && [ "$dest_dir" == "$final_path" ]; then
|
||||||
|
_ynh_apply_default_permissions $dest_dir
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$src_extract" == "false" ]]; then
|
||||||
|
if [[ -z "$src_rename" ]]; then
|
||||||
|
mv $src_filename $dest_dir
|
||||||
|
else
|
||||||
|
mv $src_filename $dest_dir/$src_rename
|
||||||
|
fi
|
||||||
|
elif [[ "$src_format" == "docker" ]]; then
|
||||||
|
"$YNH_HELPERS_DIR/vendor/docker-image-extract/docker-image-extract" -p $src_platform -o $dest_dir $src_url 2>&1
|
||||||
|
elif [[ "$src_format" == "zip" ]]; then
|
||||||
|
# Zip format
|
||||||
|
# Using of a temp directory, because unzip doesn't manage --strip-components
|
||||||
|
if $src_in_subdir; then
|
||||||
|
local tmp_dir=$(mktemp --directory)
|
||||||
|
unzip -quo $src_filename -d "$tmp_dir"
|
||||||
|
cp --archive $tmp_dir/*/. "$dest_dir"
|
||||||
|
ynh_secure_remove --file="$tmp_dir"
|
||||||
|
else
|
||||||
|
unzip -quo $src_filename -d "$dest_dir"
|
||||||
|
fi
|
||||||
|
ynh_secure_remove --file="$src_filename"
|
||||||
|
else
|
||||||
|
local strip=""
|
||||||
|
if [ "$src_in_subdir" != "false" ]; then
|
||||||
|
if [ "$src_in_subdir" == "true" ]; then
|
||||||
|
local sub_dirs=1
|
||||||
|
else
|
||||||
|
local sub_dirs="$src_in_subdir"
|
||||||
|
fi
|
||||||
|
strip="--strip-components $sub_dirs"
|
||||||
|
fi
|
||||||
|
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]]; then
|
||||||
|
tar --extract --file=$src_filename --directory="$dest_dir" $strip
|
||||||
|
else
|
||||||
|
ynh_die --message="Archive format unrecognized."
|
||||||
|
fi
|
||||||
|
ynh_secure_remove --file="$src_filename"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Apply patches
|
||||||
|
if [ -d "$YNH_APP_BASEDIR/sources/patches/" ]; then
|
||||||
|
local patches_folder=$(realpath $YNH_APP_BASEDIR/sources/patches/)
|
||||||
|
if (($(find $patches_folder -type f -name "${source_id}-*.patch" 2> /dev/null | wc --lines) > "0")); then
|
||||||
|
pushd "$dest_dir"
|
||||||
|
for p in $patches_folder/${source_id}-*.patch; do
|
||||||
|
echo $p
|
||||||
|
patch --strip=1 < $p || ynh_print_warn --message="Packagers /!\\ patch $p failed to apply"
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add supplementary files
|
||||||
|
if test -e "$YNH_APP_BASEDIR/sources/extra_files/${source_id}"; then
|
||||||
|
cp --archive $YNH_APP_BASEDIR/sources/extra_files/$source_id/. "$dest_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Keep files to be backup/restored at the end of the helper
|
||||||
|
# Assuming $dest_dir already exists
|
||||||
|
if [ -n "$keep" ]; then
|
||||||
|
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
||||||
|
local stuff_to_keep
|
||||||
|
for stuff_to_keep in $keep; do
|
||||||
|
if [ -e "$keep_dir/$stuff_to_keep" ]; then
|
||||||
|
mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")"
|
||||||
|
|
||||||
|
# We add "--no-target-directory" (short option is -T) to handle the special case
|
||||||
|
# when we "keep" a folder, but then the new setup already contains the same dir (but possibly empty)
|
||||||
|
# in which case a regular "cp" will create a copy of the directory inside the directory ...
|
||||||
|
# resulting in something like /var/www/$app/data/data instead of /var/www/$app/data
|
||||||
|
# cf https://unix.stackexchange.com/q/94831 for a more elaborate explanation on the option
|
||||||
|
cp --archive --no-target-directory "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
||||||
|
}
|
|
@ -149,8 +149,7 @@ ynh_systemd_action() {
|
||||||
# Also check the timeout using actual timestamp, because sometimes for some reason,
|
# Also check the timeout using actual timestamp, because sometimes for some reason,
|
||||||
# journalctl may take a huge time to run, and we end up waiting literally an entire hour
|
# journalctl may take a huge time to run, and we end up waiting literally an entire hour
|
||||||
# instead of 5 min ...
|
# instead of 5 min ...
|
||||||
if [[ "$(( $(date +%s) - $starttime))" -gt "$timeout" ]]
|
if [[ "$(($(date +%s) - $starttime))" -gt "$timeout" ]]; then
|
||||||
then
|
|
||||||
i=$timeout
|
i=$timeout
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,59 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Check if a YunoHost user exists
|
|
||||||
#
|
|
||||||
# usage: ynh_user_exists --username=username
|
|
||||||
# | arg: -u, --username= - the username to check
|
|
||||||
# | ret: 0 if the user exists, 1 otherwise.
|
|
||||||
#
|
|
||||||
# example: ynh_user_exists 'toto' || echo "User does not exist"
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_user_exists() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=u
|
|
||||||
local -A args_array=([u]=username=)
|
|
||||||
local username
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
yunohost user list --output-as json --quiet | jq -e ".users.\"${username}\"" >/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Retrieve a YunoHost user information
|
|
||||||
#
|
|
||||||
# usage: ynh_user_get_info --username=username --key=key
|
|
||||||
# | arg: -u, --username= - the username to retrieve info from
|
|
||||||
# | arg: -k, --key= - the key to retrieve
|
|
||||||
# | ret: the value associate to that key
|
|
||||||
#
|
|
||||||
# example: mail=$(ynh_user_get_info --username="toto" --key=mail)
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_user_get_info() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=uk
|
|
||||||
local -A args_array=([u]=username= [k]=key=)
|
|
||||||
local username
|
|
||||||
local key
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
yunohost user info "$username" --output-as json --quiet | jq -r ".$key"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the list of YunoHost users
|
|
||||||
#
|
|
||||||
# usage: ynh_user_list
|
|
||||||
# | ret: one username per line as strings
|
|
||||||
#
|
|
||||||
# example: for u in $(ynh_user_list); do ... ; done
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.4.0 or higher.
|
|
||||||
ynh_user_list() {
|
|
||||||
yunohost user list --output-as json --quiet | jq -r ".users | keys[]"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if a user exists on the system
|
# Check if a user exists on the system
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
# [packagingv1]
|
||||||
|
@ -96,8 +42,6 @@ ynh_system_group_exists() {
|
||||||
|
|
||||||
# Create a system user
|
# Create a system user
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_system_user_create --username=user_name [--home_dir=home_dir] [--use_shell] [--groups="group1 group2"]
|
# usage: ynh_system_user_create --username=user_name [--home_dir=home_dir] [--use_shell] [--groups="group1 group2"]
|
||||||
# | 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
|
||||||
|
@ -152,8 +96,6 @@ ynh_system_user_create() {
|
||||||
|
|
||||||
# Delete a system user
|
# Delete a system user
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# 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
|
||||||
#
|
#
|
406
helpers/helpers.v1.d/templating
Normal file
406
helpers/helpers.v1.d/templating
Normal file
|
@ -0,0 +1,406 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create a dedicated config file from a template
|
||||||
|
#
|
||||||
|
# usage: ynh_add_config --template="template" --destination="destination"
|
||||||
|
# | arg: -t, --template= - Template config file to use
|
||||||
|
# | arg: -d, --destination= - Destination of the config file
|
||||||
|
# | arg: -j, --jinja - Use jinja template instead of the simple `__MY_VAR__` templating format
|
||||||
|
#
|
||||||
|
# examples:
|
||||||
|
# ynh_add_config --template=".env" --destination="$install_dir/.env" # (use the template file "conf/.env" from the app's package)
|
||||||
|
# ynh_add_config --jinja --template="config.j2" --destination="$install_dir/config" # (use the template file "conf/config.j2" from the app's package)
|
||||||
|
#
|
||||||
|
# The template can be by default the name of a file in the conf directory
|
||||||
|
# of a YunoHost Package, a relative path or an absolute path.
|
||||||
|
#
|
||||||
|
# The helper will use the template `template` to generate a config file
|
||||||
|
# `destination` by replacing the following keywords with global variables
|
||||||
|
# that should be defined before calling this helper :
|
||||||
|
# ```
|
||||||
|
# __PATH__ by $path_url
|
||||||
|
# __NAME__ by $app
|
||||||
|
# __NAMETOCHANGE__ by $app
|
||||||
|
# __USER__ by $app
|
||||||
|
# __FINALPATH__ by $final_path
|
||||||
|
# __PHPVERSION__ by $YNH_PHP_VERSION (packaging v1 only, packaging v2 uses phpversion setting implicitly set by apt resource)
|
||||||
|
# __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH
|
||||||
|
# ```
|
||||||
|
# And any dynamic variables that should be defined before calling this helper like:
|
||||||
|
# ```
|
||||||
|
# __DOMAIN__ by $domain
|
||||||
|
# __APP__ by $app
|
||||||
|
# __VAR_1__ by $var_1
|
||||||
|
# __VAR_2__ by $var_2
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# ##### When --jinja is enabled
|
||||||
|
#
|
||||||
|
# This option is meant for advanced use-cases where the "simple" templating
|
||||||
|
# mode ain't enough because you need conditional blocks or loops.
|
||||||
|
#
|
||||||
|
# For a full documentation of jinja's syntax you can refer to:
|
||||||
|
# https://jinja.palletsprojects.com/en/3.1.x/templates/
|
||||||
|
#
|
||||||
|
# Note that in YunoHost context, all variables are from shell variables and therefore are strings
|
||||||
|
#
|
||||||
|
# ##### Keeping track of manual changes by the admin
|
||||||
|
#
|
||||||
|
# The helper will verify the checksum and backup the destination file
|
||||||
|
# if it's different before applying the new template.
|
||||||
|
#
|
||||||
|
# And it will calculate and store the destination file checksum
|
||||||
|
# into the app settings when configuration is done.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 4.1.0 or higher.
|
||||||
|
ynh_add_config() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=tdj
|
||||||
|
local -A args_array=([t]=template= [d]=destination= [j]=jinja)
|
||||||
|
local template
|
||||||
|
local destination
|
||||||
|
local jinja
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
local template_path
|
||||||
|
jinja="${jinja:-0}"
|
||||||
|
|
||||||
|
if [ -f "$YNH_APP_BASEDIR/conf/$template" ]; then
|
||||||
|
template_path="$YNH_APP_BASEDIR/conf/$template"
|
||||||
|
elif [ -f "$template" ]; then
|
||||||
|
template_path=$template
|
||||||
|
else
|
||||||
|
ynh_die --message="The provided template $template doesn't exist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ynh_backup_if_checksum_is_different --file="$destination"
|
||||||
|
|
||||||
|
# Make sure to set the permissions before we copy the file
|
||||||
|
# This is to cover a case where an attacker could have
|
||||||
|
# created a file beforehand to have control over it
|
||||||
|
# (cp won't overwrite ownership / modes by default...)
|
||||||
|
touch $destination
|
||||||
|
chmod 640 $destination
|
||||||
|
_ynh_apply_default_permissions $destination
|
||||||
|
|
||||||
|
if [[ "$jinja" == 1 ]]; then
|
||||||
|
# This is ran in a subshell such that the "export" does not "contaminate" the main process
|
||||||
|
(
|
||||||
|
export $(compgen -v)
|
||||||
|
j2 "$template_path" -f env -o $destination
|
||||||
|
)
|
||||||
|
else
|
||||||
|
cp -f "$template_path" "$destination"
|
||||||
|
ynh_replace_vars --file="$destination"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ynh_store_file_checksum --file="$destination"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Replace variables in a file
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# usage: ynh_replace_vars --file="file"
|
||||||
|
# | arg: -f, --file= - File where to replace variables
|
||||||
|
#
|
||||||
|
# The helper will replace the following keywords with global variables
|
||||||
|
# that should be defined before calling this helper :
|
||||||
|
# __PATH__ by $path_url
|
||||||
|
# __NAME__ by $app
|
||||||
|
# __NAMETOCHANGE__ by $app
|
||||||
|
# __USER__ by $app
|
||||||
|
# __FINALPATH__ by $final_path
|
||||||
|
# __PHPVERSION__ by $YNH_PHP_VERSION (packaging v1 only, packaging v2 uses phpversion setting implicitly set by apt resource)
|
||||||
|
# __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH
|
||||||
|
#
|
||||||
|
# And any dynamic variables that should be defined before calling this helper like:
|
||||||
|
# __DOMAIN__ by $domain
|
||||||
|
# __APP__ by $app
|
||||||
|
# __VAR_1__ by $var_1
|
||||||
|
# __VAR_2__ by $var_2
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 4.1.0 or higher.
|
||||||
|
ynh_replace_vars() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=f
|
||||||
|
local -A args_array=([f]=file=)
|
||||||
|
local file
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
# Replace specific YunoHost variables
|
||||||
|
if test -n "${path_url:-}"; then
|
||||||
|
# path_url_slash_less is path_url, or a blank value if path_url is only '/'
|
||||||
|
local path_url_slash_less=${path_url%/}
|
||||||
|
ynh_replace_string --match_string="__PATH__/" --replace_string="$path_url_slash_less/" --target_file="$file"
|
||||||
|
ynh_replace_string --match_string="__PATH__" --replace_string="$path_url" --target_file="$file"
|
||||||
|
fi
|
||||||
|
if test -n "${app:-}"; then
|
||||||
|
ynh_replace_string --match_string="__NAME__" --replace_string="$app" --target_file="$file"
|
||||||
|
ynh_replace_string --match_string="__NAMETOCHANGE__" --replace_string="$app" --target_file="$file"
|
||||||
|
ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$file"
|
||||||
|
fi
|
||||||
|
# Legacy
|
||||||
|
if test -n "${final_path:-}"; then
|
||||||
|
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$file"
|
||||||
|
ynh_replace_string --match_string="__INSTALL_DIR__" --replace_string="$final_path" --target_file="$file"
|
||||||
|
fi
|
||||||
|
# Legacy / Packaging v1 only
|
||||||
|
if dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} lt 2 && test -n "${YNH_PHP_VERSION:-}"; then
|
||||||
|
ynh_replace_string --match_string="__PHPVERSION__" --replace_string="$YNH_PHP_VERSION" --target_file="$file"
|
||||||
|
fi
|
||||||
|
if test -n "${ynh_node_load_PATH:-}"; then
|
||||||
|
ynh_replace_string --match_string="__YNH_NODE_LOAD_PATH__" --replace_string="$ynh_node_load_PATH" --target_file="$file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Replace others variables
|
||||||
|
|
||||||
|
# List other unique (__ __) variables in $file
|
||||||
|
local uniques_vars=($(grep -oP '__[A-Z0-9]+?[A-Z0-9_]*?[A-Z0-9]*?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g"))
|
||||||
|
|
||||||
|
set +o xtrace # set +x
|
||||||
|
|
||||||
|
# Do the replacement
|
||||||
|
local delimit=@
|
||||||
|
for one_var in "${uniques_vars[@]}"; do
|
||||||
|
# Validate that one_var is indeed defined
|
||||||
|
# -v checks if the variable is defined, for example:
|
||||||
|
# -v FOO tests if $FOO is defined
|
||||||
|
# -v $FOO tests if ${!FOO} is defined
|
||||||
|
# More info: https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash/17538964#comment96392525_17538964
|
||||||
|
[[ -v "${one_var:-}" ]] || ynh_die --message="Variable \$$one_var wasn't initialized when trying to replace __${one_var^^}__ in $file"
|
||||||
|
|
||||||
|
# Escape delimiter in match/replace string
|
||||||
|
match_string="__${one_var^^}__"
|
||||||
|
match_string=${match_string//${delimit}/"\\${delimit}"}
|
||||||
|
replace_string="${!one_var}"
|
||||||
|
replace_string=${replace_string//\\/\\\\}
|
||||||
|
replace_string=${replace_string//${delimit}/"\\${delimit}"}
|
||||||
|
|
||||||
|
# Actually replace (sed is used instead of ynh_replace_string to avoid triggering an epic amount of debug logs)
|
||||||
|
sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$file"
|
||||||
|
done
|
||||||
|
set -o xtrace # set -x
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get a value from heterogeneous file (yaml, json, php, python...)
|
||||||
|
#
|
||||||
|
# usage: ynh_read_var_in_file --file=PATH --key=KEY
|
||||||
|
# | arg: -f, --file= - the path to the file
|
||||||
|
# | arg: -k, --key= - the key to get
|
||||||
|
# | arg: -a, --after= - the line just before the key (in case of multiple lines with the name of the key in the file)
|
||||||
|
#
|
||||||
|
# This helpers match several var affectation use case in several languages
|
||||||
|
# We don't use jq or equivalent to keep comments and blank space in files
|
||||||
|
# This helpers work line by line, it is not able to work correctly
|
||||||
|
# if you have several identical keys in your files
|
||||||
|
#
|
||||||
|
# Example of line this helpers can managed correctly
|
||||||
|
# .yml
|
||||||
|
# title: YunoHost documentation
|
||||||
|
# email: 'yunohost@yunohost.org'
|
||||||
|
# .json
|
||||||
|
# "theme": "colib'ris",
|
||||||
|
# "port": 8102
|
||||||
|
# "some_boolean": false,
|
||||||
|
# "user": null
|
||||||
|
# .ini
|
||||||
|
# some_boolean = On
|
||||||
|
# action = "Clear"
|
||||||
|
# port = 20
|
||||||
|
# .php
|
||||||
|
# $user=
|
||||||
|
# user => 20
|
||||||
|
# .py
|
||||||
|
# USER = 8102
|
||||||
|
# user = 'https://donate.local'
|
||||||
|
# CUSTOM['user'] = 'YunoHost'
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 4.3 or higher.
|
||||||
|
ynh_read_var_in_file() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=fka
|
||||||
|
local -A args_array=([f]=file= [k]=key= [a]=after=)
|
||||||
|
local file
|
||||||
|
local key
|
||||||
|
local after
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
after="${after:-}"
|
||||||
|
|
||||||
|
[[ -f $file ]] || ynh_die --message="File $file does not exists"
|
||||||
|
|
||||||
|
set +o xtrace # set +x
|
||||||
|
|
||||||
|
# Get the line number after which we search for the variable
|
||||||
|
local line_number=1
|
||||||
|
if [[ -n "$after" ]]; then
|
||||||
|
line_number=$(grep -m1 -n $after $file | cut -d: -f1)
|
||||||
|
if [[ -z "$line_number" ]]; then
|
||||||
|
set -o xtrace # set -x
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local filename="$(basename -- "$file")"
|
||||||
|
local ext="${filename##*.}"
|
||||||
|
local endline=',;'
|
||||||
|
local assign="=>|:|="
|
||||||
|
local comments="#"
|
||||||
|
local string="\"'"
|
||||||
|
if [[ "$ext" =~ ^ini|env|toml|yml|yaml$ ]]; then
|
||||||
|
endline='#'
|
||||||
|
fi
|
||||||
|
if [[ "$ext" =~ ^ini|env$ ]]; then
|
||||||
|
comments="[;#]"
|
||||||
|
fi
|
||||||
|
if [[ "php" == "$ext" ]] || [[ "$ext" == "js" ]]; then
|
||||||
|
comments="//"
|
||||||
|
fi
|
||||||
|
local list='\[\s*['$string']?\w+['$string']?\]'
|
||||||
|
local var_part='^\s*((const|var|let)\s+)?\$?(\w+('$list')*(->|\.|\[))*\s*'
|
||||||
|
var_part+="[$string]?${key}[$string]?"
|
||||||
|
var_part+='\s*\]?\s*'
|
||||||
|
var_part+="($assign)"
|
||||||
|
var_part+='\s*'
|
||||||
|
|
||||||
|
# Extract the part after assignation sign
|
||||||
|
local expression_with_comment="$( (tail +$line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL) | head -n1)"
|
||||||
|
if [[ "$expression_with_comment" == "YNH_NULL" ]]; then
|
||||||
|
set -o xtrace # set -x
|
||||||
|
echo YNH_NULL
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove comments if needed
|
||||||
|
local expression="$(echo "$expression_with_comment" | sed "s@${comments}[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")"
|
||||||
|
|
||||||
|
local first_char="${expression:0:1}"
|
||||||
|
if [[ "$first_char" == '"' ]]; then
|
||||||
|
echo "$expression" | grep -m1 -o -P '"\K([^"](\\")?)*[^\\](?=")' | head -n1 | sed 's/\\"/"/g'
|
||||||
|
elif [[ "$first_char" == "'" ]]; then
|
||||||
|
echo "$expression" | grep -m1 -o -P "'\K([^'](\\\\')?)*[^\\\\](?=')" | head -n1 | sed "s/\\\\'/'/g"
|
||||||
|
else
|
||||||
|
echo "$expression"
|
||||||
|
fi
|
||||||
|
set -o xtrace # set -x
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set a value into heterogeneous file (yaml, json, php, python...)
|
||||||
|
#
|
||||||
|
# usage: ynh_write_var_in_file --file=PATH --key=KEY --value=VALUE
|
||||||
|
# | arg: -f, --file= - the path to the file
|
||||||
|
# | arg: -k, --key= - the key to set
|
||||||
|
# | arg: -v, --value= - the value to set
|
||||||
|
# | arg: -a, --after= - the line just before the key (in case of multiple lines with the name of the key in the file)
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 4.3 or higher.
|
||||||
|
ynh_write_var_in_file() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=fkva
|
||||||
|
local -A args_array=([f]=file= [k]=key= [v]=value= [a]=after=)
|
||||||
|
local file
|
||||||
|
local key
|
||||||
|
local value
|
||||||
|
local after
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
after="${after:-}"
|
||||||
|
|
||||||
|
[[ -f $file ]] || ynh_die --message="File $file does not exists"
|
||||||
|
|
||||||
|
set +o xtrace # set +x
|
||||||
|
|
||||||
|
# Get the line number after which we search for the variable
|
||||||
|
local after_line_number=1
|
||||||
|
if [[ -n "$after" ]]; then
|
||||||
|
after_line_number=$(grep -m1 -n $after $file | cut -d: -f1)
|
||||||
|
if [[ -z "$after_line_number" ]]; then
|
||||||
|
set -o xtrace # set -x
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local filename="$(basename -- "$file")"
|
||||||
|
local ext="${filename##*.}"
|
||||||
|
local endline=',;'
|
||||||
|
local assign="=>|:|="
|
||||||
|
local comments="#"
|
||||||
|
local string="\"'"
|
||||||
|
if [[ "$ext" =~ ^ini|env|toml|yml|yaml$ ]]; then
|
||||||
|
endline='#'
|
||||||
|
fi
|
||||||
|
if [[ "$ext" =~ ^ini|env$ ]]; then
|
||||||
|
comments="[;#]"
|
||||||
|
fi
|
||||||
|
if [[ "php" == "$ext" ]] || [[ "$ext" == "js" ]]; then
|
||||||
|
comments="//"
|
||||||
|
fi
|
||||||
|
local list='\[\s*['$string']?\w+['$string']?\]'
|
||||||
|
local var_part='^\s*((const|var|let)\s+)?\$?(\w+('$list')*(->|\.|\[))*\s*'
|
||||||
|
var_part+="[$string]?${key}[$string]?"
|
||||||
|
var_part+='\s*\]?\s*'
|
||||||
|
var_part+="($assign)"
|
||||||
|
var_part+='\s*'
|
||||||
|
|
||||||
|
# Extract the part after assignation sign
|
||||||
|
local expression_with_comment="$( (tail +$after_line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL) | head -n1)"
|
||||||
|
if [[ "$expression_with_comment" == "YNH_NULL" ]]; then
|
||||||
|
set -o xtrace # set -x
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local value_line_number="$(tail +$after_line_number ${file} | grep -m1 -n -i -P $var_part'\K.*$' | cut -d: -f1)"
|
||||||
|
value_line_number=$((after_line_number + value_line_number))
|
||||||
|
local range="${after_line_number},${value_line_number} "
|
||||||
|
|
||||||
|
# Remove comments if needed
|
||||||
|
local expression="$(echo "$expression_with_comment" | sed "s@${comments}[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")"
|
||||||
|
endline=${expression_with_comment#"$expression"}
|
||||||
|
endline="$(echo "$endline" | sed 's/\\/\\\\/g')"
|
||||||
|
value="$(echo "$value" | sed 's/\\/\\\\/g')"
|
||||||
|
value=${value//&/"\&"}
|
||||||
|
local first_char="${expression:0:1}"
|
||||||
|
delimiter=$'\001'
|
||||||
|
if [[ "$first_char" == '"' ]]; then
|
||||||
|
# \ and sed is quite complex you need 2 \\ to get one in a sed
|
||||||
|
# So we need \\\\ to go through 2 sed
|
||||||
|
value="$(echo "$value" | sed 's/"/\\\\"/g')"
|
||||||
|
sed -ri "${range}s$delimiter"'(^'"${var_part}"'")([^"]|\\")*("[\s;,]*)(\s*'$comments'.*)?$'$delimiter'\1'"${value}"'"'"${endline}${delimiter}i" ${file}
|
||||||
|
elif [[ "$first_char" == "'" ]]; then
|
||||||
|
# \ and sed is quite complex you need 2 \\ to get one in a sed
|
||||||
|
# However double quotes implies to double \\ to
|
||||||
|
# So we need \\\\\\\\ to go through 2 sed and 1 double quotes str
|
||||||
|
value="$(echo "$value" | sed "s/'/\\\\\\\\'/g")"
|
||||||
|
sed -ri "${range}s$delimiter(^${var_part}')([^']|\\')*('"'[\s,;]*)(\s*'$comments'.*)?$'$delimiter'\1'"${value}'${endline}${delimiter}i" ${file}
|
||||||
|
else
|
||||||
|
if [[ "$value" == *"'"* ]] || [[ "$value" == *'"'* ]] || [[ "$ext" =~ ^php|py|json|js$ ]]; then
|
||||||
|
value='\"'"$(echo "$value" | sed 's/"/\\\\"/g')"'\"'
|
||||||
|
fi
|
||||||
|
if [[ "$ext" =~ ^yaml|yml$ ]]; then
|
||||||
|
value=" $value"
|
||||||
|
fi
|
||||||
|
sed -ri "${range}s$delimiter(^${var_part}).*\$$delimiter\1${value}${endline}${delimiter}i" ${file}
|
||||||
|
fi
|
||||||
|
set -o xtrace # set -x
|
||||||
|
}
|
||||||
|
|
||||||
|
# Render templates with Jinja2
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# Attention : Variables should be exported before calling this helper to be
|
||||||
|
# accessible inside templates.
|
||||||
|
#
|
||||||
|
# usage: ynh_render_template some_template output_path
|
||||||
|
# | arg: some_template - Template file to be rendered
|
||||||
|
# | arg: output_path - The path where the output will be redirected to
|
||||||
|
ynh_render_template() {
|
||||||
|
local template_path=$1
|
||||||
|
local output_path=$2
|
||||||
|
mkdir -p "$(dirname $output_path)"
|
||||||
|
# Taken from https://stackoverflow.com/a/35009576
|
||||||
|
python3 -c 'import os, sys, jinja2; sys.stdout.write(
|
||||||
|
jinja2.Template(sys.stdin.read()
|
||||||
|
).render(os.environ));' < $template_path > $output_path
|
||||||
|
}
|
|
@ -22,8 +22,7 @@ YNH_APP_BASEDIR=${YNH_APP_BASEDIR:-$(realpath ..)}
|
||||||
ynh_exit_properly() {
|
ynh_exit_properly() {
|
||||||
local exit_code=$?
|
local exit_code=$?
|
||||||
|
|
||||||
if [[ "${YNH_APP_ACTION:-}" =~ ^install$|^upgrade$|^restore$ ]]
|
if [[ "${YNH_APP_ACTION:-}" =~ ^install$|^upgrade$|^restore$ ]]; then
|
||||||
then
|
|
||||||
rm -rf "/var/cache/yunohost/download/"
|
rm -rf "/var/cache/yunohost/download/"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -67,327 +66,10 @@ ynh_abort_if_errors() {
|
||||||
}
|
}
|
||||||
|
|
||||||
# When running an app script with packaging format >= 2, auto-enable ynh_abort_if_errors except for remove script
|
# When running an app script with packaging format >= 2, auto-enable ynh_abort_if_errors except for remove script
|
||||||
if [[ "${YNH_CONTEXT:-}" != "regenconf" ]] && dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} ge 2 && [[ ${YNH_APP_ACTION} != "remove" ]]
|
if [[ "${YNH_CONTEXT:-}" != "regenconf" ]] && dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} ge 2 && [[ ${YNH_APP_ACTION} != "remove" ]]; then
|
||||||
then
|
|
||||||
ynh_abort_if_errors
|
ynh_abort_if_errors
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Download, check integrity, uncompress and patch the source from app.src
|
|
||||||
#
|
|
||||||
# usage: ynh_setup_source --dest_dir=dest_dir [--source_id=source_id] [--keep="file1 file2"] [--full_replace]
|
|
||||||
# | arg: -d, --dest_dir= - Directory where to setup sources
|
|
||||||
# | arg: -s, --source_id= - Name of the source, defaults to `main` (when the sources resource exists in manifest.toml) or (legacy) `app` otherwise
|
|
||||||
# | arg: -k, --keep= - Space-separated list of files/folders that will be backup/restored in $dest_dir, such as a config file you don't want to overwrite. For example 'conf.json secrets.json logs' (no trailing `/` for folders)
|
|
||||||
# | arg: -r, --full_replace= - Remove previous sources before installing new sources (can be 1 or 0, default to 0)
|
|
||||||
#
|
|
||||||
# #### New 'sources' resources
|
|
||||||
#
|
|
||||||
# (See also the resources documentation which may be more complete?)
|
|
||||||
#
|
|
||||||
# This helper will read infos from the 'sources' resources in the manifest.toml of the app
|
|
||||||
# and expect a structure like:
|
|
||||||
#
|
|
||||||
# ```toml
|
|
||||||
# [resources.sources]
|
|
||||||
# [resources.sources.main]
|
|
||||||
# url = "https://some.address.to/download/the/app/archive"
|
|
||||||
# sha256 = "0123456789abcdef" # The sha256 sum of the asset obtained from the URL
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# ##### Optional flags
|
|
||||||
#
|
|
||||||
# ```text
|
|
||||||
# format = "tar.gz"/xz/bz2 # automatically guessed from the extension of the URL, but can be set explicitly. Will use `tar` to extract
|
|
||||||
# "zip" # automatically guessed from the extension of the URL, but can be set explicitly. Will use `unzip` to extract
|
|
||||||
# "docker" # useful to extract files from an already-built docker image (instead of rebuilding them locally). Will use `docker-image-extract` to extract
|
|
||||||
# "whatever" # an arbitrary value, not really meaningful except to imply that the file won't be extracted
|
|
||||||
#
|
|
||||||
# in_subdir = true # default, there's an intermediate subdir in the archive before accessing the actual files
|
|
||||||
# false # sources are directly in the archive root
|
|
||||||
# n # (special cases) an integer representing a number of subdirs levels to get rid of
|
|
||||||
#
|
|
||||||
# extract = true # default if file is indeed an archive such as .zip, .tar.gz, .tar.bz2, ...
|
|
||||||
# = false # default if file 'format' is not set and the file is not to be extracted because it is not an archive but a script or binary or whatever asset.
|
|
||||||
# # in which case the file will only be `mv`ed to the location possibly renamed using the `rename` value
|
|
||||||
#
|
|
||||||
# rename = "whatever_your_want" # to be used for convenience when `extract` is false and the default name of the file is not practical
|
|
||||||
# platform = "linux/amd64" # (defaults to "linux/$YNH_ARCH") to be used in conjonction with `format = "docker"` to specify which architecture to extract for
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# You may also define assets url and checksum per-architectures such as:
|
|
||||||
# ```toml
|
|
||||||
# [resources.sources]
|
|
||||||
# [resources.sources.main]
|
|
||||||
# amd64.url = "https://some.address.to/download/the/app/archive/when/amd64"
|
|
||||||
# amd64.sha256 = "0123456789abcdef"
|
|
||||||
# armhf.url = "https://some.address.to/download/the/app/archive/when/armhf"
|
|
||||||
# armhf.sha256 = "fedcba9876543210"
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# In which case ynh_setup_source --dest_dir="$install_dir" will automatically pick the appropriate source depending on the arch
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# #### Legacy format '.src'
|
|
||||||
#
|
|
||||||
# This helper will read `conf/${source_id}.src`, download and install the sources.
|
|
||||||
#
|
|
||||||
# The src file need to contains:
|
|
||||||
# ```
|
|
||||||
# SOURCE_URL=Address to download the app archive
|
|
||||||
# SOURCE_SUM=Sha256 sum
|
|
||||||
# SOURCE_FORMAT=tar.gz
|
|
||||||
# SOURCE_IN_SUBDIR=false
|
|
||||||
# SOURCE_FILENAME=example.tar.gz
|
|
||||||
# SOURCE_EXTRACT=(true|false)
|
|
||||||
# SOURCE_PLATFORM=linux/arm64/v8
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# The helper will:
|
|
||||||
# - Download the specific URL if there is no local archive
|
|
||||||
# - Check the integrity with the specific sha256 sum
|
|
||||||
# - Uncompress the archive to `$dest_dir`.
|
|
||||||
# - If `in_subdir` is true, the first level directory of the archive will be removed.
|
|
||||||
# - If `in_subdir` is a numeric value, the N first level directories will be removed.
|
|
||||||
# - Patches named `sources/patches/${src_id}-*.patch` will be applied to `$dest_dir`
|
|
||||||
# - Extra files in `sources/extra_files/$src_id` will be copied to dest_dir
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_setup_source() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=dsk
|
|
||||||
local -A args_array=([d]=dest_dir= [s]=source_id= [k]=keep= [r]=full_replace=)
|
|
||||||
local dest_dir
|
|
||||||
local source_id
|
|
||||||
local keep
|
|
||||||
local full_replace
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
keep="${keep:-}"
|
|
||||||
full_replace="${full_replace:-0}"
|
|
||||||
|
|
||||||
if test -e $YNH_APP_BASEDIR/manifest.toml && cat $YNH_APP_BASEDIR/manifest.toml | toml_to_json | jq -e '.resources.sources' >/dev/null
|
|
||||||
then
|
|
||||||
source_id="${source_id:-main}"
|
|
||||||
local sources_json=$(cat $YNH_APP_BASEDIR/manifest.toml | toml_to_json | jq ".resources.sources[\"$source_id\"]")
|
|
||||||
if jq -re ".url" <<< "$sources_json"
|
|
||||||
then
|
|
||||||
local arch_prefix=""
|
|
||||||
else
|
|
||||||
local arch_prefix=".$YNH_ARCH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
local src_url="$(jq -r "$arch_prefix.url" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_sum="$(jq -r "$arch_prefix.sha256" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_sumprg="sha256sum"
|
|
||||||
local src_format="$(jq -r ".format" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_in_subdir="$(jq -r ".in_subdir" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_extract="$(jq -r ".extract" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_platform="$(jq -r ".platform" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_rename="$(jq -r ".rename" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
|
|
||||||
[[ -n "$src_url" ]] || ynh_die "No URL defined for source $source_id$arch_prefix ?"
|
|
||||||
[[ -n "$src_sum" ]] || ynh_die "No sha256 sum defined for source $source_id$arch_prefix ?"
|
|
||||||
|
|
||||||
if [[ -z "$src_format" ]]
|
|
||||||
then
|
|
||||||
if [[ "$src_url" =~ ^.*\.zip$ ]] || [[ "$src_url" =~ ^.*/zipball/.*$ ]]
|
|
||||||
then
|
|
||||||
src_format="zip"
|
|
||||||
elif [[ "$src_url" =~ ^.*\.tar\.gz$ ]] || [[ "$src_url" =~ ^.*\.tgz$ ]] || [[ "$src_url" =~ ^.*/tar\.gz/.*$ ]] || [[ "$src_url" =~ ^.*/tarball/.*$ ]]
|
|
||||||
then
|
|
||||||
src_format="tar.gz"
|
|
||||||
elif [[ "$src_url" =~ ^.*\.tar\.xz$ ]]
|
|
||||||
then
|
|
||||||
src_format="tar.xz"
|
|
||||||
elif [[ "$src_url" =~ ^.*\.tar\.bz2$ ]]
|
|
||||||
then
|
|
||||||
src_format="tar.bz2"
|
|
||||||
elif [[ -z "$src_extract" ]]
|
|
||||||
then
|
|
||||||
src_extract="false"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
source_id="${source_id:-app}"
|
|
||||||
local src_file_path="$YNH_APP_BASEDIR/conf/${source_id}.src"
|
|
||||||
|
|
||||||
# Load value from configuration file (see above for a small doc about this file
|
|
||||||
# format)
|
|
||||||
local src_url=$(grep 'SOURCE_URL=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_sum=$(grep 'SOURCE_SUM=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_sumprg=$(grep 'SOURCE_SUM_PRG=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_format=$(grep 'SOURCE_FORMAT=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_in_subdir=$(grep 'SOURCE_IN_SUBDIR=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_rename=$(grep 'SOURCE_FILENAME=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_extract=$(grep 'SOURCE_EXTRACT=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_platform=$(grep 'SOURCE_PLATFORM=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Default value
|
|
||||||
src_sumprg=${src_sumprg:-sha256sum}
|
|
||||||
src_in_subdir=${src_in_subdir:-true}
|
|
||||||
src_format=${src_format:-tar.gz}
|
|
||||||
src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]')
|
|
||||||
src_extract=${src_extract:-true}
|
|
||||||
|
|
||||||
if [[ "$src_extract" != "true" ]] && [[ "$src_extract" != "false" ]]
|
|
||||||
then
|
|
||||||
ynh_die "For source $source_id, expected either 'true' or 'false' for the extract parameter"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# (Unused?) mecanism where one can have the file in a special local cache to not have to download it...
|
|
||||||
local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${source_id}"
|
|
||||||
|
|
||||||
# Gotta use this trick with 'dirname' because source_id may contain slashes x_x
|
|
||||||
mkdir -p $(dirname /var/cache/yunohost/download/${YNH_APP_ID}/${source_id})
|
|
||||||
src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${source_id}"
|
|
||||||
|
|
||||||
if [ "$src_format" = "docker" ]; then
|
|
||||||
src_platform="${src_platform:-"linux/$YNH_ARCH"}"
|
|
||||||
else
|
|
||||||
if test -e "$local_src"; then
|
|
||||||
cp $local_src $src_filename
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?"
|
|
||||||
|
|
||||||
# If the file was prefetched but somehow doesn't match the sum, rm and redownload it
|
|
||||||
if [ -e "$src_filename" ] && ! echo "${src_sum} ${src_filename}" | ${src_sumprg} --check --status
|
|
||||||
then
|
|
||||||
rm -f "$src_filename"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Only redownload the file if it wasnt prefetched
|
|
||||||
if [ ! -e "$src_filename" ]
|
|
||||||
then
|
|
||||||
# NB. we have to declare the var as local first,
|
|
||||||
# otherwise 'local foo=$(false) || echo 'pwet'" does'nt work
|
|
||||||
# because local always return 0 ...
|
|
||||||
local out
|
|
||||||
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
|
||||||
out=$(wget --tries 3 --no-dns-cache --timeout 900 --no-verbose --output-document=$src_filename $src_url 2>&1) \
|
|
||||||
|| ynh_die --message="$out"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check the control sum
|
|
||||||
if ! echo "${src_sum} ${src_filename}" | ${src_sumprg} --check --status
|
|
||||||
then
|
|
||||||
local actual_sum="$(${src_sumprg} ${src_filename} | cut --delimiter=' ' --fields=1)"
|
|
||||||
local actual_size="$(du -hs ${src_filename} | cut --fields=1)"
|
|
||||||
rm -f ${src_filename}
|
|
||||||
ynh_die --message="Corrupt source for ${src_url}: Expected sha256sum to be ${src_sum} but got ${actual_sum} (size: ${actual_size})."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Keep files to be backup/restored at the end of the helper
|
|
||||||
# Assuming $dest_dir already exists
|
|
||||||
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
|
||||||
if [ -n "$keep" ] && [ -e "$dest_dir" ]; then
|
|
||||||
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
|
||||||
mkdir -p $keep_dir
|
|
||||||
local stuff_to_keep
|
|
||||||
for stuff_to_keep in $keep; do
|
|
||||||
if [ -e "$dest_dir/$stuff_to_keep" ]; then
|
|
||||||
mkdir --parents "$(dirname "$keep_dir/$stuff_to_keep")"
|
|
||||||
cp --archive "$dest_dir/$stuff_to_keep" "$keep_dir/$stuff_to_keep"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$full_replace" -eq 1 ]; then
|
|
||||||
ynh_secure_remove --file="$dest_dir"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract source into the app dir
|
|
||||||
mkdir --parents "$dest_dir"
|
|
||||||
|
|
||||||
if [ -n "${install_dir:-}" ] && [ "$dest_dir" == "$install_dir" ]; then
|
|
||||||
_ynh_apply_default_permissions $dest_dir
|
|
||||||
fi
|
|
||||||
if [ -n "${final_path:-}" ] && [ "$dest_dir" == "$final_path" ]; then
|
|
||||||
_ynh_apply_default_permissions $dest_dir
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$src_extract" == "false" ]]; then
|
|
||||||
if [[ -z "$src_rename" ]]
|
|
||||||
then
|
|
||||||
mv $src_filename $dest_dir
|
|
||||||
else
|
|
||||||
mv $src_filename $dest_dir/$src_rename
|
|
||||||
fi
|
|
||||||
elif [[ "$src_format" == "docker" ]]; then
|
|
||||||
"$YNH_HELPERS_DIR/vendor/docker-image-extract/docker-image-extract" -p $src_platform -o $dest_dir $src_url 2>&1
|
|
||||||
elif [[ "$src_format" == "zip" ]]; then
|
|
||||||
# Zip format
|
|
||||||
# Using of a temp directory, because unzip doesn't manage --strip-components
|
|
||||||
if $src_in_subdir; then
|
|
||||||
local tmp_dir=$(mktemp --directory)
|
|
||||||
unzip -quo $src_filename -d "$tmp_dir"
|
|
||||||
cp --archive $tmp_dir/*/. "$dest_dir"
|
|
||||||
ynh_secure_remove --file="$tmp_dir"
|
|
||||||
else
|
|
||||||
unzip -quo $src_filename -d "$dest_dir"
|
|
||||||
fi
|
|
||||||
ynh_secure_remove --file="$src_filename"
|
|
||||||
else
|
|
||||||
local strip=""
|
|
||||||
if [ "$src_in_subdir" != "false" ]; then
|
|
||||||
if [ "$src_in_subdir" == "true" ]; then
|
|
||||||
local sub_dirs=1
|
|
||||||
else
|
|
||||||
local sub_dirs="$src_in_subdir"
|
|
||||||
fi
|
|
||||||
strip="--strip-components $sub_dirs"
|
|
||||||
fi
|
|
||||||
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]]; then
|
|
||||||
tar --extract --file=$src_filename --directory="$dest_dir" $strip
|
|
||||||
else
|
|
||||||
ynh_die --message="Archive format unrecognized."
|
|
||||||
fi
|
|
||||||
ynh_secure_remove --file="$src_filename"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Apply patches
|
|
||||||
if [ -d "$YNH_APP_BASEDIR/sources/patches/" ]; then
|
|
||||||
local patches_folder=$(realpath $YNH_APP_BASEDIR/sources/patches/)
|
|
||||||
if (($(find $patches_folder -type f -name "${source_id}-*.patch" 2>/dev/null | wc --lines) > "0")); then
|
|
||||||
pushd "$dest_dir"
|
|
||||||
for p in $patches_folder/${source_id}-*.patch; do
|
|
||||||
echo $p
|
|
||||||
patch --strip=1 <$p || ynh_print_warn --message="Packagers /!\\ patch $p failed to apply"
|
|
||||||
done
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add supplementary files
|
|
||||||
if test -e "$YNH_APP_BASEDIR/sources/extra_files/${source_id}"; then
|
|
||||||
cp --archive $YNH_APP_BASEDIR/sources/extra_files/$source_id/. "$dest_dir"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Keep files to be backup/restored at the end of the helper
|
|
||||||
# Assuming $dest_dir already exists
|
|
||||||
if [ -n "$keep" ]; then
|
|
||||||
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
|
||||||
local stuff_to_keep
|
|
||||||
for stuff_to_keep in $keep; do
|
|
||||||
if [ -e "$keep_dir/$stuff_to_keep" ]; then
|
|
||||||
mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")"
|
|
||||||
|
|
||||||
# We add "--no-target-directory" (short option is -T) to handle the special case
|
|
||||||
# when we "keep" a folder, but then the new setup already contains the same dir (but possibly empty)
|
|
||||||
# in which case a regular "cp" will create a copy of the directory inside the directory ...
|
|
||||||
# resulting in something like /var/www/$app/data/data instead of /var/www/$app/data
|
|
||||||
# cf https://unix.stackexchange.com/q/94831 for a more elaborate explanation on the option
|
|
||||||
cp --archive --no-target-directory "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
|
||||||
}
|
|
||||||
|
|
||||||
# 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)
|
||||||
#
|
#
|
||||||
# usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ...
|
# usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ...
|
||||||
|
@ -447,435 +129,6 @@ ynh_local_curl() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a dedicated config file from a template
|
|
||||||
#
|
|
||||||
# usage: ynh_add_config --template="template" --destination="destination"
|
|
||||||
# | arg: -t, --template= - Template config file to use
|
|
||||||
# | arg: -d, --destination= - Destination of the config file
|
|
||||||
# | arg: -j, --jinja - Use jinja template instead of legacy __MY_VAR__
|
|
||||||
#
|
|
||||||
# examples:
|
|
||||||
# ynh_add_config --template=".env" --destination="$install_dir/.env" use the template file "../conf/.env"
|
|
||||||
# ynh_add_config --jinja --template="config.j2" --destination="$install_dir/config" use the template file "../conf/config.j2"
|
|
||||||
# ynh_add_config --template="/etc/nginx/sites-available/default" --destination="etc/nginx/sites-available/mydomain.conf"
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## How it works in "legacy" mode
|
|
||||||
##
|
|
||||||
# The template can be by default the name of a file in the conf directory
|
|
||||||
# of a YunoHost Package, a relative path or an absolute path.
|
|
||||||
#
|
|
||||||
# The helper will use the template `template` to generate a config file
|
|
||||||
# `destination` by replacing the following keywords with global variables
|
|
||||||
# that should be defined before calling this helper :
|
|
||||||
# ```
|
|
||||||
# __PATH__ by $path_url
|
|
||||||
# __NAME__ by $app
|
|
||||||
# __NAMETOCHANGE__ by $app
|
|
||||||
# __USER__ by $app
|
|
||||||
# __FINALPATH__ by $final_path
|
|
||||||
# __PHPVERSION__ by $YNH_PHP_VERSION (packaging v1 only, packaging v2 uses phpversion setting implicitly set by apt resource)
|
|
||||||
# __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH
|
|
||||||
# ```
|
|
||||||
# And any dynamic variables that should be defined before calling this helper like:
|
|
||||||
# ```
|
|
||||||
# __DOMAIN__ by $domain
|
|
||||||
# __APP__ by $app
|
|
||||||
# __VAR_1__ by $var_1
|
|
||||||
# __VAR_2__ by $var_2
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## When --jinja is enabled
|
|
||||||
##
|
|
||||||
# For a full documentation of the template you can refer to: https://jinja.palletsprojects.com/en/3.1.x/templates/
|
|
||||||
# In Yunohost context there are no really some specificity except that all variable passed are of type string.
|
|
||||||
# So here are some example of recommended usage:
|
|
||||||
#
|
|
||||||
# If you need a conditional block
|
|
||||||
#
|
|
||||||
# {% if should_my_block_be_shown == 'true' %}
|
|
||||||
# ...
|
|
||||||
# {% endif %}
|
|
||||||
#
|
|
||||||
# or
|
|
||||||
#
|
|
||||||
# {% if should_my_block_be_shown == '1' %}
|
|
||||||
# ...
|
|
||||||
# {% endif %}
|
|
||||||
#
|
|
||||||
# If you need to iterate with loop:
|
|
||||||
#
|
|
||||||
# {% for yolo in var_with_multiline_value.splitlines() %}
|
|
||||||
# ...
|
|
||||||
# {% endfor %}
|
|
||||||
#
|
|
||||||
# or
|
|
||||||
#
|
|
||||||
# {% for jail in my_var_with_coma.split(',') %}
|
|
||||||
# ...
|
|
||||||
# {% endfor %}
|
|
||||||
#
|
|
||||||
# The helper will verify the checksum and backup the destination file
|
|
||||||
# if it's different before applying the new template.
|
|
||||||
#
|
|
||||||
# And it will calculate and store the destination file checksum
|
|
||||||
# into the app settings when configuration is done.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_add_config() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=tdj
|
|
||||||
local -A args_array=([t]=template= [d]=destination= [j]=jinja)
|
|
||||||
local template
|
|
||||||
local destination
|
|
||||||
local jinja
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
local template_path
|
|
||||||
jinja="${jinja:-0}"
|
|
||||||
|
|
||||||
if [ -f "$YNH_APP_BASEDIR/conf/$template" ]; then
|
|
||||||
template_path="$YNH_APP_BASEDIR/conf/$template"
|
|
||||||
elif [ -f "$template" ]; then
|
|
||||||
template_path=$template
|
|
||||||
else
|
|
||||||
ynh_die --message="The provided template $template doesn't exist"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_backup_if_checksum_is_different --file="$destination"
|
|
||||||
|
|
||||||
# Make sure to set the permissions before we copy the file
|
|
||||||
# This is to cover a case where an attacker could have
|
|
||||||
# created a file beforehand to have control over it
|
|
||||||
# (cp won't overwrite ownership / modes by default...)
|
|
||||||
touch $destination
|
|
||||||
chmod 640 $destination
|
|
||||||
_ynh_apply_default_permissions $destination
|
|
||||||
|
|
||||||
if [[ "$jinja" == 1 ]]
|
|
||||||
then
|
|
||||||
# This is ran in a subshell such that the "export" does not "contaminate" the main process
|
|
||||||
(
|
|
||||||
export $(compgen -v)
|
|
||||||
j2 "$template_path" -f env -o $destination
|
|
||||||
)
|
|
||||||
else
|
|
||||||
cp -f "$template_path" "$destination"
|
|
||||||
ynh_replace_vars --file="$destination"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_store_file_checksum --file="$destination"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Replace variables in a file
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# usage: ynh_replace_vars --file="file"
|
|
||||||
# | arg: -f, --file= - File where to replace variables
|
|
||||||
#
|
|
||||||
# The helper will replace the following keywords with global variables
|
|
||||||
# that should be defined before calling this helper :
|
|
||||||
# __PATH__ by $path_url
|
|
||||||
# __NAME__ by $app
|
|
||||||
# __NAMETOCHANGE__ by $app
|
|
||||||
# __USER__ by $app
|
|
||||||
# __FINALPATH__ by $final_path
|
|
||||||
# __PHPVERSION__ by $YNH_PHP_VERSION (packaging v1 only, packaging v2 uses phpversion setting implicitly set by apt resource)
|
|
||||||
# __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH
|
|
||||||
#
|
|
||||||
# And any dynamic variables that should be defined before calling this helper like:
|
|
||||||
# __DOMAIN__ by $domain
|
|
||||||
# __APP__ by $app
|
|
||||||
# __VAR_1__ by $var_1
|
|
||||||
# __VAR_2__ by $var_2
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_replace_vars() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=f
|
|
||||||
local -A args_array=([f]=file=)
|
|
||||||
local file
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
# Replace specific YunoHost variables
|
|
||||||
if test -n "${path_url:-}"; then
|
|
||||||
# path_url_slash_less is path_url, or a blank value if path_url is only '/'
|
|
||||||
local path_url_slash_less=${path_url%/}
|
|
||||||
ynh_replace_string --match_string="__PATH__/" --replace_string="$path_url_slash_less/" --target_file="$file"
|
|
||||||
ynh_replace_string --match_string="__PATH__" --replace_string="$path_url" --target_file="$file"
|
|
||||||
fi
|
|
||||||
if test -n "${app:-}"; then
|
|
||||||
ynh_replace_string --match_string="__NAME__" --replace_string="$app" --target_file="$file"
|
|
||||||
ynh_replace_string --match_string="__NAMETOCHANGE__" --replace_string="$app" --target_file="$file"
|
|
||||||
ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$file"
|
|
||||||
fi
|
|
||||||
# Legacy
|
|
||||||
if test -n "${final_path:-}"; then
|
|
||||||
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$file"
|
|
||||||
ynh_replace_string --match_string="__INSTALL_DIR__" --replace_string="$final_path" --target_file="$file"
|
|
||||||
fi
|
|
||||||
# Legacy / Packaging v1 only
|
|
||||||
if dpkg --compare-versions ${YNH_APP_PACKAGING_FORMAT:-0} lt 2 && test -n "${YNH_PHP_VERSION:-}"; then
|
|
||||||
ynh_replace_string --match_string="__PHPVERSION__" --replace_string="$YNH_PHP_VERSION" --target_file="$file"
|
|
||||||
fi
|
|
||||||
if test -n "${ynh_node_load_PATH:-}"; then
|
|
||||||
ynh_replace_string --match_string="__YNH_NODE_LOAD_PATH__" --replace_string="$ynh_node_load_PATH" --target_file="$file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Replace others variables
|
|
||||||
|
|
||||||
# List other unique (__ __) variables in $file
|
|
||||||
local uniques_vars=($(grep -oP '__[A-Z0-9]+?[A-Z0-9_]*?[A-Z0-9]*?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g"))
|
|
||||||
|
|
||||||
set +o xtrace # set +x
|
|
||||||
|
|
||||||
# Do the replacement
|
|
||||||
local delimit=@
|
|
||||||
for one_var in "${uniques_vars[@]}"; do
|
|
||||||
# Validate that one_var is indeed defined
|
|
||||||
# -v checks if the variable is defined, for example:
|
|
||||||
# -v FOO tests if $FOO is defined
|
|
||||||
# -v $FOO tests if ${!FOO} is defined
|
|
||||||
# More info: https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash/17538964#comment96392525_17538964
|
|
||||||
[[ -v "${one_var:-}" ]] || ynh_die --message="Variable \$$one_var wasn't initialized when trying to replace __${one_var^^}__ in $file"
|
|
||||||
|
|
||||||
# Escape delimiter in match/replace string
|
|
||||||
match_string="__${one_var^^}__"
|
|
||||||
match_string=${match_string//${delimit}/"\\${delimit}"}
|
|
||||||
replace_string="${!one_var}"
|
|
||||||
replace_string=${replace_string//\\/\\\\}
|
|
||||||
replace_string=${replace_string//${delimit}/"\\${delimit}"}
|
|
||||||
|
|
||||||
# Actually replace (sed is used instead of ynh_replace_string to avoid triggering an epic amount of debug logs)
|
|
||||||
sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$file"
|
|
||||||
done
|
|
||||||
set -o xtrace # set -x
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get a value from heterogeneous file (yaml, json, php, python...)
|
|
||||||
#
|
|
||||||
# usage: ynh_read_var_in_file --file=PATH --key=KEY
|
|
||||||
# | arg: -f, --file= - the path to the file
|
|
||||||
# | arg: -k, --key= - the key to get
|
|
||||||
# | arg: -a, --after= - the line just before the key (in case of multiple lines with the name of the key in the file)
|
|
||||||
#
|
|
||||||
# This helpers match several var affectation use case in several languages
|
|
||||||
# We don't use jq or equivalent to keep comments and blank space in files
|
|
||||||
# This helpers work line by line, it is not able to work correctly
|
|
||||||
# if you have several identical keys in your files
|
|
||||||
#
|
|
||||||
# Example of line this helpers can managed correctly
|
|
||||||
# .yml
|
|
||||||
# title: YunoHost documentation
|
|
||||||
# email: 'yunohost@yunohost.org'
|
|
||||||
# .json
|
|
||||||
# "theme": "colib'ris",
|
|
||||||
# "port": 8102
|
|
||||||
# "some_boolean": false,
|
|
||||||
# "user": null
|
|
||||||
# .ini
|
|
||||||
# some_boolean = On
|
|
||||||
# action = "Clear"
|
|
||||||
# port = 20
|
|
||||||
# .php
|
|
||||||
# $user=
|
|
||||||
# user => 20
|
|
||||||
# .py
|
|
||||||
# USER = 8102
|
|
||||||
# user = 'https://donate.local'
|
|
||||||
# CUSTOM['user'] = 'YunoHost'
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.3 or higher.
|
|
||||||
ynh_read_var_in_file() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=fka
|
|
||||||
local -A args_array=([f]=file= [k]=key= [a]=after=)
|
|
||||||
local file
|
|
||||||
local key
|
|
||||||
local after
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
after="${after:-}"
|
|
||||||
|
|
||||||
[[ -f $file ]] || ynh_die --message="File $file does not exists"
|
|
||||||
|
|
||||||
set +o xtrace # set +x
|
|
||||||
|
|
||||||
# Get the line number after which we search for the variable
|
|
||||||
local line_number=1
|
|
||||||
if [[ -n "$after" ]]; then
|
|
||||||
line_number=$(grep -m1 -n $after $file | cut -d: -f1)
|
|
||||||
if [[ -z "$line_number" ]]; then
|
|
||||||
set -o xtrace # set -x
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
local filename="$(basename -- "$file")"
|
|
||||||
local ext="${filename##*.}"
|
|
||||||
local endline=',;'
|
|
||||||
local assign="=>|:|="
|
|
||||||
local comments="#"
|
|
||||||
local string="\"'"
|
|
||||||
if [[ "$ext" =~ ^ini|env|toml|yml|yaml$ ]]; then
|
|
||||||
endline='#'
|
|
||||||
fi
|
|
||||||
if [[ "$ext" =~ ^ini|env$ ]]; then
|
|
||||||
comments="[;#]"
|
|
||||||
fi
|
|
||||||
if [[ "php" == "$ext" ]] || [[ "$ext" == "js" ]]; then
|
|
||||||
comments="//"
|
|
||||||
fi
|
|
||||||
local list='\[\s*['$string']?\w+['$string']?\]'
|
|
||||||
local var_part='^\s*((const|var|let)\s+)?\$?(\w+('$list')*(->|\.|\[))*\s*'
|
|
||||||
var_part+="[$string]?${key}[$string]?"
|
|
||||||
var_part+='\s*\]?\s*'
|
|
||||||
var_part+="($assign)"
|
|
||||||
var_part+='\s*'
|
|
||||||
|
|
||||||
# Extract the part after assignation sign
|
|
||||||
local expression_with_comment="$((tail +$line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL) | head -n1)"
|
|
||||||
if [[ "$expression_with_comment" == "YNH_NULL" ]]; then
|
|
||||||
set -o xtrace # set -x
|
|
||||||
echo YNH_NULL
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove comments if needed
|
|
||||||
local expression="$(echo "$expression_with_comment" | sed "s@${comments}[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")"
|
|
||||||
|
|
||||||
local first_char="${expression:0:1}"
|
|
||||||
if [[ "$first_char" == '"' ]]; then
|
|
||||||
echo "$expression" | grep -m1 -o -P '"\K([^"](\\")?)*[^\\](?=")' | head -n1 | sed 's/\\"/"/g'
|
|
||||||
elif [[ "$first_char" == "'" ]]; then
|
|
||||||
echo "$expression" | grep -m1 -o -P "'\K([^'](\\\\')?)*[^\\\\](?=')" | head -n1 | sed "s/\\\\'/'/g"
|
|
||||||
else
|
|
||||||
echo "$expression"
|
|
||||||
fi
|
|
||||||
set -o xtrace # set -x
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set a value into heterogeneous file (yaml, json, php, python...)
|
|
||||||
#
|
|
||||||
# usage: ynh_write_var_in_file --file=PATH --key=KEY --value=VALUE
|
|
||||||
# | arg: -f, --file= - the path to the file
|
|
||||||
# | arg: -k, --key= - the key to set
|
|
||||||
# | arg: -v, --value= - the value to set
|
|
||||||
# | arg: -a, --after= - the line just before the key (in case of multiple lines with the name of the key in the file)
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.3 or higher.
|
|
||||||
ynh_write_var_in_file() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=fkva
|
|
||||||
local -A args_array=([f]=file= [k]=key= [v]=value= [a]=after=)
|
|
||||||
local file
|
|
||||||
local key
|
|
||||||
local value
|
|
||||||
local after
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
after="${after:-}"
|
|
||||||
|
|
||||||
[[ -f $file ]] || ynh_die --message="File $file does not exists"
|
|
||||||
|
|
||||||
set +o xtrace # set +x
|
|
||||||
|
|
||||||
# Get the line number after which we search for the variable
|
|
||||||
local after_line_number=1
|
|
||||||
if [[ -n "$after" ]]; then
|
|
||||||
after_line_number=$(grep -m1 -n $after $file | cut -d: -f1)
|
|
||||||
if [[ -z "$after_line_number" ]]; then
|
|
||||||
set -o xtrace # set -x
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
local filename="$(basename -- "$file")"
|
|
||||||
local ext="${filename##*.}"
|
|
||||||
local endline=',;'
|
|
||||||
local assign="=>|:|="
|
|
||||||
local comments="#"
|
|
||||||
local string="\"'"
|
|
||||||
if [[ "$ext" =~ ^ini|env|toml|yml|yaml$ ]]; then
|
|
||||||
endline='#'
|
|
||||||
fi
|
|
||||||
if [[ "$ext" =~ ^ini|env$ ]]; then
|
|
||||||
comments="[;#]"
|
|
||||||
fi
|
|
||||||
if [[ "php" == "$ext" ]] || [[ "$ext" == "js" ]]; then
|
|
||||||
comments="//"
|
|
||||||
fi
|
|
||||||
local list='\[\s*['$string']?\w+['$string']?\]'
|
|
||||||
local var_part='^\s*((const|var|let)\s+)?\$?(\w+('$list')*(->|\.|\[))*\s*'
|
|
||||||
var_part+="[$string]?${key}[$string]?"
|
|
||||||
var_part+='\s*\]?\s*'
|
|
||||||
var_part+="($assign)"
|
|
||||||
var_part+='\s*'
|
|
||||||
|
|
||||||
# Extract the part after assignation sign
|
|
||||||
local expression_with_comment="$((tail +$after_line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL) | head -n1)"
|
|
||||||
if [[ "$expression_with_comment" == "YNH_NULL" ]]; then
|
|
||||||
set -o xtrace # set -x
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
local value_line_number="$(tail +$after_line_number ${file} | grep -m1 -n -i -P $var_part'\K.*$' | cut -d: -f1)"
|
|
||||||
value_line_number=$((after_line_number + value_line_number))
|
|
||||||
local range="${after_line_number},${value_line_number} "
|
|
||||||
|
|
||||||
# Remove comments if needed
|
|
||||||
local expression="$(echo "$expression_with_comment" | sed "s@${comments}[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")"
|
|
||||||
endline=${expression_with_comment#"$expression"}
|
|
||||||
endline="$(echo "$endline" | sed 's/\\/\\\\/g')"
|
|
||||||
value="$(echo "$value" | sed 's/\\/\\\\/g')"
|
|
||||||
value=${value//&/"\&"}
|
|
||||||
local first_char="${expression:0:1}"
|
|
||||||
delimiter=$'\001'
|
|
||||||
if [[ "$first_char" == '"' ]]; then
|
|
||||||
# \ and sed is quite complex you need 2 \\ to get one in a sed
|
|
||||||
# So we need \\\\ to go through 2 sed
|
|
||||||
value="$(echo "$value" | sed 's/"/\\\\"/g')"
|
|
||||||
sed -ri "${range}s$delimiter"'(^'"${var_part}"'")([^"]|\\")*("[\s;,]*)(\s*'$comments'.*)?$'$delimiter'\1'"${value}"'"'"${endline}${delimiter}i" ${file}
|
|
||||||
elif [[ "$first_char" == "'" ]]; then
|
|
||||||
# \ and sed is quite complex you need 2 \\ to get one in a sed
|
|
||||||
# However double quotes implies to double \\ to
|
|
||||||
# So we need \\\\\\\\ to go through 2 sed and 1 double quotes str
|
|
||||||
value="$(echo "$value" | sed "s/'/\\\\\\\\'/g")"
|
|
||||||
sed -ri "${range}s$delimiter(^${var_part}')([^']|\\')*('"'[\s,;]*)(\s*'$comments'.*)?$'$delimiter'\1'"${value}'${endline}${delimiter}i" ${file}
|
|
||||||
else
|
|
||||||
if [[ "$value" == *"'"* ]] || [[ "$value" == *'"'* ]] || [[ "$ext" =~ ^php|py|json|js$ ]]; then
|
|
||||||
value='\"'"$(echo "$value" | sed 's/"/\\\\"/g')"'\"'
|
|
||||||
fi
|
|
||||||
if [[ "$ext" =~ ^yaml|yml$ ]]; then
|
|
||||||
value=" $value"
|
|
||||||
fi
|
|
||||||
sed -ri "${range}s$delimiter(^${var_part}).*\$$delimiter\1${value}${endline}${delimiter}i" ${file}
|
|
||||||
fi
|
|
||||||
set -o xtrace # set -x
|
|
||||||
}
|
|
||||||
|
|
||||||
# Render templates with Jinja2
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# Attention : Variables should be exported before calling this helper to be
|
|
||||||
# accessible inside templates.
|
|
||||||
#
|
|
||||||
# usage: ynh_render_template some_template output_path
|
|
||||||
# | arg: some_template - Template file to be rendered
|
|
||||||
# | arg: output_path - The path where the output will be redirected to
|
|
||||||
ynh_render_template() {
|
|
||||||
local template_path=$1
|
|
||||||
local output_path=$2
|
|
||||||
mkdir -p "$(dirname $output_path)"
|
|
||||||
# Taken from https://stackoverflow.com/a/35009576
|
|
||||||
python3 -c 'import os, sys, jinja2; sys.stdout.write(
|
|
||||||
jinja2.Template(sys.stdin.read()
|
|
||||||
).render(os.environ));' <$template_path >$output_path
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fetch the Debian release codename
|
# Fetch the Debian release codename
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
# [packagingv1]
|
||||||
|
@ -894,8 +147,7 @@ _acceptable_path_to_delete() {
|
||||||
local forbidden_paths=$(ls -d / /* /{var,home,usr}/* /etc/{default,sudoers.d,yunohost,cron*} /etc/yunohost/{apps,domains,hooks.d} /opt/yunohost 2> /dev/null)
|
local forbidden_paths=$(ls -d / /* /{var,home,usr}/* /etc/{default,sudoers.d,yunohost,cron*} /etc/yunohost/{apps,domains,hooks.d} /opt/yunohost 2> /dev/null)
|
||||||
|
|
||||||
# Legacy : A couple apps still have data in /home/$app ...
|
# Legacy : A couple apps still have data in /home/$app ...
|
||||||
if [[ -n "${app:-}" ]]
|
if [[ -n "${app:-}" ]]; then
|
||||||
then
|
|
||||||
forbidden_paths=$(echo "$forbidden_paths" | grep -v "/home/$app")
|
forbidden_paths=$(echo "$forbidden_paths" | grep -v "/home/$app")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -960,19 +212,16 @@ ynh_read_manifest() {
|
||||||
|
|
||||||
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.
|
||||||
if [ -e "$YNH_APP_BASEDIR/manifest.json" ]
|
if [ -e "$YNH_APP_BASEDIR/manifest.json" ]; then
|
||||||
then
|
|
||||||
manifest="$YNH_APP_BASEDIR/manifest.json"
|
manifest="$YNH_APP_BASEDIR/manifest.json"
|
||||||
elif [ -e "$YNH_APP_BASEDIR/manifest.toml" ]
|
elif [ -e "$YNH_APP_BASEDIR/manifest.toml" ]; then
|
||||||
then
|
|
||||||
manifest="$YNH_APP_BASEDIR/manifest.toml"
|
manifest="$YNH_APP_BASEDIR/manifest.toml"
|
||||||
else
|
else
|
||||||
ynh_die --message "No manifest found !?"
|
ynh_die --message "No manifest found !?"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if echo "$manifest" | grep -q '\.json$'
|
if echo "$manifest" | grep -q '\.json$'; then
|
||||||
then
|
|
||||||
jq ".$manifest_key" "$manifest" --raw-output
|
jq ".$manifest_key" "$manifest" --raw-output
|
||||||
else
|
else
|
||||||
cat "$manifest" | python3 -c 'import json, toml, sys; print(json.dumps(toml.load(sys.stdin)))' | jq ".$manifest_key" --raw-output
|
cat "$manifest" | python3 -c 'import json, toml, sys; print(json.dumps(toml.load(sys.stdin)))' | jq ".$manifest_key" --raw-output
|
||||||
|
@ -1132,8 +381,7 @@ _ynh_apply_default_permissions() {
|
||||||
# Crons should be owned by root
|
# Crons should be owned by root
|
||||||
# Also we don't want systemd conf, nginx conf or others stuff to be owned by the app,
|
# Also we don't want systemd conf, nginx conf or others stuff to be owned by the app,
|
||||||
# otherwise they could self-edit their own systemd conf and escalate privilege
|
# otherwise they could self-edit their own systemd conf and escalate privilege
|
||||||
if grep -qE '^(/etc/cron|/etc/php|/etc/nginx/conf.d|/etc/fail2ban|/etc/systemd/system)' <<< "$target"
|
if grep -qE '^(/etc/cron|/etc/php|/etc/nginx/conf.d|/etc/fail2ban|/etc/systemd/system)' <<< "$target"; then
|
||||||
then
|
|
||||||
chmod 400 $target
|
chmod 400 $target
|
||||||
chown root:root $target
|
chown root:root $target
|
||||||
fi
|
fi
|
||||||
|
@ -1146,3 +394,57 @@ int_to_bool() {
|
||||||
toml_to_json() {
|
toml_to_json() {
|
||||||
python3 -c 'import toml, json, sys; print(json.dumps(toml.load(sys.stdin)))'
|
python3 -c 'import toml, json, sys; print(json.dumps(toml.load(sys.stdin)))'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if a YunoHost user exists
|
||||||
|
#
|
||||||
|
# usage: ynh_user_exists --username=username
|
||||||
|
# | arg: -u, --username= - the username to check
|
||||||
|
# | ret: 0 if the user exists, 1 otherwise.
|
||||||
|
#
|
||||||
|
# example: ynh_user_exists 'toto' || echo "User does not exist"
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
|
ynh_user_exists() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=u
|
||||||
|
local -A args_array=([u]=username=)
|
||||||
|
local username
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
yunohost user list --output-as json --quiet | jq -e ".users.\"${username}\"" > /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Retrieve a YunoHost user information
|
||||||
|
#
|
||||||
|
# usage: ynh_user_get_info --username=username --key=key
|
||||||
|
# | arg: -u, --username= - the username to retrieve info from
|
||||||
|
# | arg: -k, --key= - the key to retrieve
|
||||||
|
# | ret: the value associate to that key
|
||||||
|
#
|
||||||
|
# example: mail=$(ynh_user_get_info --username="toto" --key=mail)
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
|
ynh_user_get_info() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=uk
|
||||||
|
local -A args_array=([u]=username= [k]=key=)
|
||||||
|
local username
|
||||||
|
local key
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
yunohost user info "$username" --output-as json --quiet | jq -r ".$key"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the list of YunoHost users
|
||||||
|
#
|
||||||
|
# usage: ynh_user_list
|
||||||
|
# | ret: one username per line as strings
|
||||||
|
#
|
||||||
|
# example: for u in $(ynh_user_list); do ... ; done
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.4.0 or higher.
|
||||||
|
ynh_user_list() {
|
||||||
|
yunohost user list --output-as json --quiet | jq -r ".users | keys[]"
|
||||||
|
}
|
||||||
|
|
|
@ -1,213 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Install others YunoHost apps
|
|
||||||
#
|
|
||||||
# usage: ynh_install_apps --apps="appfoo?domain=domain.foo&path=/foo appbar?domain=domain.bar&path=/bar&admin=USER&language=fr&is_public=1&pass?word=pass&port=666"
|
|
||||||
# | arg: -a, --apps= - apps to install
|
|
||||||
#
|
|
||||||
# Requires YunoHost version *.*.* or higher.
|
|
||||||
ynh_install_apps() {
|
|
||||||
# ============ Argument parsing =============
|
|
||||||
local -A args_array=([a]=apps=)
|
|
||||||
local apps
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
# ===========================================
|
|
||||||
|
|
||||||
# Split the list of apps in an array
|
|
||||||
local apps_list=($(echo $apps | tr " " "\n"))
|
|
||||||
local apps_dependencies=""
|
|
||||||
|
|
||||||
# For each app
|
|
||||||
for one_app_and_its_args in "${apps_list[@]}"
|
|
||||||
do
|
|
||||||
# Retrieve the name of the app (part before ?)
|
|
||||||
local one_app=$(cut -d "?" -f1 <<< "$one_app_and_its_args")
|
|
||||||
[ -z "$one_app" ] && ynh_die "You didn't provided a YunoHost app to install"
|
|
||||||
|
|
||||||
yunohost tools update apps
|
|
||||||
|
|
||||||
# Installing or upgrading the app depending if it's installed or not
|
|
||||||
if ! yunohost app list --output-as json --quiet | jq -e --arg id $one_app '.apps[] | select(.id == $id)' >/dev/null
|
|
||||||
then
|
|
||||||
# Retrieve the arguments of the app (part after ?)
|
|
||||||
local one_argument=""
|
|
||||||
if [[ "$one_app_and_its_args" == *"?"* ]]; then
|
|
||||||
one_argument=$(cut -d "?" -f2- <<< "$one_app_and_its_args")
|
|
||||||
one_argument="--args $one_argument"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install the app with its arguments
|
|
||||||
yunohost app install $one_app $one_argument
|
|
||||||
else
|
|
||||||
# Upgrade the app
|
|
||||||
yunohost app upgrade $one_app
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -z "$apps_dependencies" ]
|
|
||||||
then
|
|
||||||
apps_dependencies="$apps_dependencies, $one_app"
|
|
||||||
else
|
|
||||||
apps_dependencies="$one_app"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
ynh_app_setting_set --key=apps_dependencies --value="$apps_dependencies"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove other YunoHost apps
|
|
||||||
#
|
|
||||||
# Other YunoHost apps will be removed only if no other apps need them.
|
|
||||||
#
|
|
||||||
# usage: ynh_remove_apps
|
|
||||||
#
|
|
||||||
# Requires YunoHost version *.*.* or higher.
|
|
||||||
ynh_remove_apps() {
|
|
||||||
# Retrieve the apps dependencies of the app
|
|
||||||
local apps_dependencies=$(ynh_app_setting_get --key=apps_dependencies)
|
|
||||||
ynh_app_setting_delete --key=apps_dependencies
|
|
||||||
|
|
||||||
if [ ! -z "$apps_dependencies" ]
|
|
||||||
then
|
|
||||||
# Split the list of apps dependencies in an array
|
|
||||||
local apps_dependencies_list=($(echo $apps_dependencies | tr ", " "\n"))
|
|
||||||
|
|
||||||
# For each apps dependencies
|
|
||||||
for one_app in "${apps_dependencies_list[@]}"
|
|
||||||
do
|
|
||||||
# Retrieve the list of installed apps
|
|
||||||
local installed_apps_list=$(yunohost app list --output-as json --quiet | jq -r .apps[].id)
|
|
||||||
local required_by=""
|
|
||||||
local installed_app_required_by=""
|
|
||||||
|
|
||||||
# For each other installed app
|
|
||||||
for one_installed_app in $installed_apps_list
|
|
||||||
do
|
|
||||||
# Retrieve the other apps dependencies
|
|
||||||
one_installed_apps_dependencies=$(ynh_app_setting_get --app=$one_installed_app --key=apps_dependencies)
|
|
||||||
if [ ! -z "$one_installed_apps_dependencies" ]
|
|
||||||
then
|
|
||||||
one_installed_apps_dependencies_list=($(echo $one_installed_apps_dependencies | tr ", " "\n"))
|
|
||||||
|
|
||||||
# For each dependency of the other apps
|
|
||||||
for one_installed_app_dependency in "${one_installed_apps_dependencies_list[@]}"
|
|
||||||
do
|
|
||||||
if [[ $one_installed_app_dependency == $one_app ]]; then
|
|
||||||
required_by="$required_by $one_installed_app"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# If $one_app is no more required
|
|
||||||
if [[ -z "$required_by" ]]
|
|
||||||
then
|
|
||||||
# Remove $one_app
|
|
||||||
ynh_print_info "Removing of $one_app"
|
|
||||||
yunohost app remove $one_app --purge
|
|
||||||
else
|
|
||||||
ynh_print_info "$one_app was not removed because it's still required by${required_by}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Spawn a Bash shell with the app environment loaded
|
|
||||||
#
|
|
||||||
# usage: ynh_spawn_app_shell --app="app"
|
|
||||||
# | arg: -a, --app= - the app ID
|
|
||||||
#
|
|
||||||
# examples:
|
|
||||||
# ynh_spawn_app_shell --app="APP" <<< 'echo "$USER"'
|
|
||||||
# ynh_spawn_app_shell --app="APP" < /tmp/some_script.bash
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 11.0.* or higher, and that the app relies on packaging v2 or higher.
|
|
||||||
# The spawned shell will have environment variables loaded and environment files sourced
|
|
||||||
# from the app's service configuration file (defaults to $app.service, overridable by the packager with `service` setting).
|
|
||||||
# If the app relies on a specific PHP version, then `php` will be aliased that version. The PHP command will also be appended with the `phpflags` settings.
|
|
||||||
ynh_spawn_app_shell() {
|
|
||||||
# ============ Argument parsing =============
|
|
||||||
local -A args_array=([a]=app=)
|
|
||||||
local app
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
# ===========================================
|
|
||||||
|
|
||||||
# Force Bash to be used to run this helper
|
|
||||||
if [[ ! $0 =~ \/?bash$ ]]
|
|
||||||
then
|
|
||||||
ynh_print_warn "Please use Bash as shell"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make sure the app is installed
|
|
||||||
local installed_apps_list=($(yunohost app list --output-as json --quiet | jq -r .apps[].id))
|
|
||||||
if [[ " ${installed_apps_list[*]} " != *" ${app} "* ]]
|
|
||||||
then
|
|
||||||
ynh_print_warn "$app is not in the apps list"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make sure the app has its own user
|
|
||||||
if ! id -u "$app" &>/dev/null; then
|
|
||||||
ynh_print_warn "There is no \"$app\" system user"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make sure the app has an install_dir setting
|
|
||||||
local install_dir=$(ynh_app_setting_get --key=install_dir)
|
|
||||||
if [ -z "$install_dir" ]
|
|
||||||
then
|
|
||||||
ynh_print_warn "$app has no install_dir setting (does it use packaging format >=2?)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Load the app's service name, or default to $app
|
|
||||||
local service=$(ynh_app_setting_get --key=service)
|
|
||||||
[ -z "$service" ] && service=$app;
|
|
||||||
|
|
||||||
# Export HOME variable
|
|
||||||
export HOME=$install_dir;
|
|
||||||
|
|
||||||
# Load the Environment variables from the app's service
|
|
||||||
local env_var=$(systemctl show $service.service -p "Environment" --value)
|
|
||||||
[ -n "$env_var" ] && export $env_var;
|
|
||||||
|
|
||||||
# Force `php` to its intended version
|
|
||||||
# We use `eval`+`export` since `alias` is not propagated to subshells, even with `export`
|
|
||||||
local php_version=$(ynh_app_setting_get --key=php_version)
|
|
||||||
local phpflags=$(ynh_app_setting_get --key=phpflags)
|
|
||||||
if [ -n "$php_version" ]
|
|
||||||
then
|
|
||||||
eval "php() { php${php_version} ${phpflags} \"\$@\"; }"
|
|
||||||
export -f php
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Source the EnvironmentFiles from the app's service
|
|
||||||
local env_files=($(systemctl show $service.service -p "EnvironmentFiles" --value))
|
|
||||||
if [ ${#env_files[*]} -gt 0 ]
|
|
||||||
then
|
|
||||||
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
|
|
||||||
set -a
|
|
||||||
for file in ${env_files[*]}
|
|
||||||
do
|
|
||||||
[[ $file = /* ]] && source $file
|
|
||||||
done
|
|
||||||
set +a
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Activate the Python environment, if it exists
|
|
||||||
if [ -f $install_dir/venv/bin/activate ]
|
|
||||||
then
|
|
||||||
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
|
|
||||||
set -a
|
|
||||||
source $install_dir/venv/bin/activate
|
|
||||||
set +a
|
|
||||||
fi
|
|
||||||
|
|
||||||
# cd into the WorkingDirectory set in the service, or default to the install_dir
|
|
||||||
local env_dir=$(systemctl show $service.service -p "WorkingDirectory" --value)
|
|
||||||
[ -z $env_dir ] && env_dir=$install_dir;
|
|
||||||
cd $env_dir
|
|
||||||
|
|
||||||
# Spawn the app shell
|
|
||||||
su -s /bin/bash $app
|
|
||||||
}
|
|
|
@ -4,27 +4,21 @@ YNH_APT_INSTALL_DEPENDENCIES_REPLACE="true"
|
||||||
|
|
||||||
# Define and install dependencies with a equivs control file
|
# Define and install dependencies with a equivs control file
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
# example : ynh_apt_install_dependencies dep1 dep2 "dep3|dep4|dep5"
|
||||||
#
|
#
|
||||||
# This helper can/should only be called once per app
|
# usage: ynh_apt_install_dependencies dep [dep [...]]
|
||||||
#
|
|
||||||
# example : ynh_install_app_dependencies dep1 dep2 "dep3|dep4|dep5"
|
|
||||||
#
|
|
||||||
# usage: ynh_install_app_dependencies dep [dep [...]]
|
|
||||||
# | arg: dep - the package name to install in dependence.
|
# | arg: dep - the package name to install in dependence.
|
||||||
# | arg: "dep1|dep2|…" - You can specify alternatives. It will require to install (dep1 or dep2, etc).
|
# | arg: "dep1|dep2|…" - You can specify alternatives. It will require to install (dep1 or dep2, etc).
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_apt_install_dependencies() {
|
ynh_apt_install_dependencies() {
|
||||||
local dependencies=$@
|
|
||||||
# Add a comma for each space between packages. But not add a comma if the space separate a version specification. (See below)
|
# 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="$(sed 's/\([^\<=\>]\)\ \([^(]\)/\1, \2/g' <<< "$@" | sed 's/|/ | /')"
|
||||||
local dependencies=${dependencies//|/ | }
|
|
||||||
local version=$(ynh_read_manifest "version")
|
local version=$(ynh_read_manifest "version")
|
||||||
local app_ynh_deps="${app//_/-}-ynh-deps" # Replace all '_' by '-', and append -ynh-deps
|
local app_ynh_deps="${app//_/-}-ynh-deps" # Replace all '_' by '-', and append -ynh-deps
|
||||||
|
|
||||||
# Handle specific versions
|
# Handle specific versions
|
||||||
if [[ "$dependencies" =~ [\<=\>] ]]; then
|
if grep '[<=>]' <<< "$dependencies"; then
|
||||||
# Replace version specifications by relationships syntax
|
# Replace version specifications by relationships syntax
|
||||||
# https://www.debian.org/doc/debian-policy/ch-relationships.html
|
# https://www.debian.org/doc/debian-policy/ch-relationships.html
|
||||||
# Sed clarification
|
# Sed clarification
|
||||||
|
@ -33,7 +27,7 @@ ynh_apt_install_dependencies() {
|
||||||
# \+ matches one or more occurence of the previous characters, for >= or >>.
|
# \+ matches one or more occurence of the previous characters, for >= or >>.
|
||||||
# [^,]\+ matches all characters except ','
|
# [^,]\+ matches all characters except ','
|
||||||
# Ex: 'package>=1.0' will be replaced by 'package (>= 1.0)'
|
# Ex: 'package>=1.0' will be replaced by 'package (>= 1.0)'
|
||||||
dependencies="$(echo "$dependencies" | sed 's/\([^(\<=\>]\)\([\<=\>]\+\)\([^,]\+\)/\1 (\2 \3)/g')"
|
dependencies="$(sed 's/\([^(\<=\>]\)\([\<=\>]\+\)\([^,]\+\)/\1 (\2 \3)/g' <<< "$dependencies")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ############################## #
|
# ############################## #
|
||||||
|
@ -43,10 +37,9 @@ ynh_apt_install_dependencies() {
|
||||||
# Check for specific php dependencies which requires sury
|
# Check for specific php dependencies which requires sury
|
||||||
# This grep will for example return "7.4" if dependencies is "foo bar php7.4-pwet php-gni"
|
# This grep will for example return "7.4" if dependencies is "foo bar php7.4-pwet php-gni"
|
||||||
# The (?<=php) syntax corresponds to lookbehind ;)
|
# The (?<=php) syntax corresponds to lookbehind ;)
|
||||||
local specific_php_version=$(echo $dependencies | grep -oP '(?<=php)[0-9.]+(?=-|\>|)' | sort -u)
|
local specific_php_version=$(grep -oP '(?<=php)[0-9.]+(?=-|\>|)' <<< "$dependencies" | sort -u)
|
||||||
|
|
||||||
if [[ -n "$specific_php_version" ]]
|
if [[ -n "$specific_php_version" ]]; then
|
||||||
then
|
|
||||||
# Cover a small edge case where a packager could have specified "php7.4-pwet php5-gni" which is confusing
|
# Cover a small edge case where a packager could have specified "php7.4-pwet php5-gni" which is confusing
|
||||||
[[ $(echo $specific_php_version | wc -l) -eq 1 ]] \
|
[[ $(echo $specific_php_version | wc -l) -eq 1 ]] \
|
||||||
|| ynh_die "Inconsistent php versions in dependencies ... found : $specific_php_version"
|
|| ynh_die "Inconsistent php versions in dependencies ... found : $specific_php_version"
|
||||||
|
@ -57,21 +50,16 @@ ynh_apt_install_dependencies() {
|
||||||
|
|
||||||
# If the PHP version changed, remove the old fpm conf
|
# If the PHP version changed, remove the old fpm conf
|
||||||
if [ -n "$old_php_version" ] && [ "$old_php_version" != "$specific_php_version" ]; then
|
if [ -n "$old_php_version" ] && [ "$old_php_version" != "$specific_php_version" ]; then
|
||||||
local old_php_fpm_config_dir=$(ynh_app_setting_get --key=fpm_config_dir)
|
if [[ -f "/etc/php/$php_version/fpm/pool.d/$app.conf" ]]; then
|
||||||
local old_php_finalphpconf="$old_php_fpm_config_dir/pool.d/$app.conf"
|
ynh_backup_if_checksum_is_different "/etc/php/$php_version/fpm/pool.d/$app.conf"
|
||||||
|
ynh_config_remove_phpfpm
|
||||||
if [[ -f "$old_php_finalphpconf" ]]
|
|
||||||
then
|
|
||||||
ynh_backup_if_checksum_is_different "$old_php_finalphpconf"
|
|
||||||
ynh_remove_fpm_config
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
# Store php_version into the config of this app
|
# Store php_version into the config of this app
|
||||||
ynh_app_setting_set --key=php_version --value=$specific_php_version
|
ynh_app_setting_set --key=php_version --value=$specific_php_version
|
||||||
|
|
||||||
# Set the default php version back as the default version for php-cli.
|
# Set the default php version back as the default version for php-cli.
|
||||||
if test -e /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
if test -e /usr/bin/php$YNH_DEFAULT_PHP_VERSION; then
|
||||||
then
|
|
||||||
update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
||||||
fi
|
fi
|
||||||
elif grep --quiet 'php' <<< "$dependencies"; then
|
elif grep --quiet 'php' <<< "$dependencies"; then
|
||||||
|
@ -81,79 +69,78 @@ ynh_apt_install_dependencies() {
|
||||||
# Specific tweak related to Postgresql (cf end of the helper)
|
# Specific tweak related to Postgresql (cf end of the helper)
|
||||||
local psql_installed="$(_ynh_apt_package_is_installed "postgresql-$PSQL_VERSION" && echo yes || echo no)"
|
local psql_installed="$(_ynh_apt_package_is_installed "postgresql-$PSQL_VERSION" && echo yes || echo no)"
|
||||||
|
|
||||||
# The first time we run ynh_install_app_dependencies, we will replace the
|
# The first time we run ynh_apt_install_dependencies, we will replace the
|
||||||
# entire control file (This is in particular meant to cover the case of
|
# entire control file (This is in particular meant to cover the case of
|
||||||
# upgrade script where ynh_install_app_dependencies is called with this
|
# upgrade script where ynh_apt_install_dependencies is called with this
|
||||||
# expected effect) Otherwise, any subsequent call will add dependencies
|
# expected effect) Otherwise, any subsequent call will add dependencies
|
||||||
# to those already present in the equivs control file.
|
# to those already present in the equivs control file.
|
||||||
if [[ $YNH_APT_INSTALL_DEPENDENCIES_REPLACE == "true" ]]
|
if [[ $YNH_APT_INSTALL_DEPENDENCIES_REPLACE == "true" ]]; then
|
||||||
then
|
|
||||||
YNH_APT_INSTALL_DEPENDENCIES_REPLACE="false"
|
YNH_APT_INSTALL_DEPENDENCIES_REPLACE="false"
|
||||||
else
|
else
|
||||||
local current_dependencies=""
|
local current_dependencies=""
|
||||||
if _ynh_apt_package_is_installed "${app_ynh_deps}"
|
if _ynh_apt_package_is_installed "${app_ynh_deps}"; then
|
||||||
then
|
|
||||||
current_dependencies="$(dpkg-query --show --showformat='${Depends}' ${app_ynh_deps}) "
|
current_dependencies="$(dpkg-query --show --showformat='${Depends}' ${app_ynh_deps}) "
|
||||||
current_dependencies=${current_dependencies// | /|}
|
current_dependencies=${current_dependencies// | /|}
|
||||||
fi
|
fi
|
||||||
dependencies="$current_dependencies, $dependencies"
|
dependencies="$current_dependencies, $dependencies"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# #############################
|
# ################
|
||||||
# Actual install using equivs #
|
# Actual install #
|
||||||
# #############################
|
# ################
|
||||||
|
|
||||||
# Prepare the virtual-dependency control file for equivs
|
# Prepare the virtual-dependency control file for dpkg-deb --build
|
||||||
local TMPDIR=$(mktemp --directory)
|
local TMPDIR=$(mktemp --directory)
|
||||||
cat >${TMPDIR}/control <<EOF # Make a control file for equivs-build
|
mkdir -p ${TMPDIR}/${app_ynh_deps}/DEBIAN
|
||||||
|
# For some reason, dpkg-deb insists for folder perm to be 755 and sometimes it's 777 o_O?
|
||||||
|
chmod -R 755 ${TMPDIR}/${app_ynh_deps}
|
||||||
|
|
||||||
|
cat > ${TMPDIR}/${app_ynh_deps}/DEBIAN/control << EOF
|
||||||
Section: misc
|
Section: misc
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Package: ${app_ynh_deps}
|
Package: ${app_ynh_deps}
|
||||||
Version: ${version}
|
Version: ${version}
|
||||||
Depends: ${dependencies}
|
Depends: ${dependencies//,,/,}
|
||||||
Architecture: all
|
Architecture: all
|
||||||
|
Maintainer: root@localhost
|
||||||
Description: Fake package for ${app} (YunoHost app) dependencies
|
Description: Fake package for ${app} (YunoHost app) dependencies
|
||||||
This meta-package is only responsible of installing its dependencies.
|
This meta-package is only responsible of installing its dependencies.
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Make sure to delete equivs' legacy compat file
|
|
||||||
# It's now handle somewhat magically through the control file
|
|
||||||
rm -f /usr/share/equivs/template/debian/compat
|
|
||||||
|
|
||||||
_ynh_apt update
|
_ynh_apt update
|
||||||
|
|
||||||
_ynh_wait_dpkg_free
|
_ynh_wait_dpkg_free
|
||||||
|
|
||||||
(
|
|
||||||
# NB: this is in a subshell (though not sure why exactly not just use pushd/popd...)
|
|
||||||
cd "$TMPDIR"
|
|
||||||
# Install the fake package without its dependencies with dpkg --force-depends
|
# Install the fake package without its dependencies with dpkg --force-depends
|
||||||
LC_ALL=C equivs-build ./control 2>&1
|
if ! LC_ALL=C dpkg-deb --build "${TMPDIR}/${app_ynh_deps}" "${TMPDIR}/${app_ynh_deps}.deb" > "${TMPDIR}/dpkg_log" 2>&1; then
|
||||||
LC_ALL=C dpkg --force-depends --install "./${app_ynh_deps}_${version}_all.deb" 2>&1 | tee ./dpkg_log
|
cat "${TMPDIR}/dpkg_log" >&2
|
||||||
)
|
ynh_die --message="Unable to install dependencies"
|
||||||
|
fi
|
||||||
|
# Don't crash in case of error, because is nicely covered by the following line
|
||||||
|
LC_ALL=C dpkg --force-depends --install "${TMPDIR}/${app_ynh_deps}.deb" 2>&1 | tee "${TMPDIR}/dpkg_log" || true
|
||||||
|
|
||||||
# Then install the missing dependencies with apt install
|
# Then install the missing dependencies with apt install
|
||||||
_ynh_apt_install --fix-broken \
|
_ynh_apt_install --fix-broken || {
|
||||||
|| { # If the installation failed
|
# If the installation failed
|
||||||
# (the following is ran inside { } to not start a subshell otherwise ynh_die wouldnt exit the original process)
|
# (the following is ran inside { } to not start a subshell otherwise ynh_die wouldnt exit the original process)
|
||||||
# Parse the list of problematic dependencies from dpkg's log ...
|
# Parse the list of problematic dependencies from dpkg's log ...
|
||||||
# (relevant lines look like: "foo-ynh-deps depends on bar; however:")
|
# (relevant lines look like: "foo-ynh-deps depends on bar; however:")
|
||||||
local problematic_dependencies="$(cat $TMPDIR/dpkg_log | grep -oP '(?<=-ynh-deps depends on ).*(?=; however)' | tr '\n' ' ')"
|
cat $TMPDIR/dpkg_log
|
||||||
|
local problematic_dependencies="$(grep -oP '(?<=-ynh-deps depends on ).*(?=; however)' $TMPDIR/dpkg_log | tr '\n' ' ')"
|
||||||
# Fake an install of those dependencies to see the errors
|
# Fake an install of those dependencies to see the errors
|
||||||
# The sed command here is, Print only from 'Reading state info' to the end.
|
# The sed command here is, Print only from 'Reading state info' to the end.
|
||||||
[[ -n "$problematic_dependencies" ]] && _ynh_apt_install $problematic_dependencies --dry-run 2>&1 | sed --quiet '/Reading state info/,$p' | grep -v "fix-broken\|Reading state info" >&2
|
[[ -n "$problematic_dependencies" ]] && _ynh_apt_install $problematic_dependencies --dry-run 2>&1 | sed --quiet '/Reading state info/,$p' | grep -v "fix-broken\|Reading state info" >&2
|
||||||
ynh_die "Unable to install dependencies"
|
ynh_die "Unable to install apt dependencies"
|
||||||
}
|
}
|
||||||
rm --recursive --force "$TMPDIR" # Remove the temp dir.
|
rm --recursive --force "$TMPDIR" # Remove the temp dir.
|
||||||
|
|
||||||
# check if the package is actually installed
|
# check if the package is actually installed
|
||||||
_ynh_apt_package_is_installed "${app_ynh_deps}" || ynh_die "Unable to install dependencies"
|
_ynh_apt_package_is_installed "${app_ynh_deps}" || ynh_die "Unable to install apt dependencies"
|
||||||
|
|
||||||
# Specific tweak related to Postgresql
|
# Specific tweak related to Postgresql
|
||||||
# -> trigger postgresql regenconf if we may have just installed postgresql
|
# -> trigger postgresql regenconf if we may have just installed postgresql
|
||||||
local psql_installed2="$(_ynh_apt_package_is_installed "postgresql-$PSQL_VERSION" && echo yes || echo no)"
|
local psql_installed2="$(_ynh_apt_package_is_installed "postgresql-$PSQL_VERSION" && echo yes || echo no)"
|
||||||
if [[ "$psql_installed" != "$psql_installed2" ]]
|
if [[ "$psql_installed" != "$psql_installed2" ]]; then
|
||||||
then
|
|
||||||
yunohost tools regen-conf postgresql
|
yunohost tools regen-conf postgresql
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -161,13 +148,9 @@ EOF
|
||||||
|
|
||||||
# Remove fake package and its dependencies
|
# Remove fake package and its dependencies
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# Dependencies will removed only if no other package need them.
|
# Dependencies will removed only if no other package need them.
|
||||||
#
|
#
|
||||||
# usage: ynh_apt_remove_dependencies
|
# usage: ynh_apt_remove_dependencies
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_apt_remove_dependencies() {
|
ynh_apt_remove_dependencies() {
|
||||||
local app_ynh_deps="${app//_/-}-ynh-deps" # Replace all '_' by '-', and append -ynh-deps
|
local app_ynh_deps="${app//_/-}-ynh-deps" # Replace all '_' by '-', and append -ynh-deps
|
||||||
|
|
||||||
|
@ -179,30 +162,25 @@ ynh_apt_remove_dependencies() {
|
||||||
|
|
||||||
# Edge case where the app dep may be on hold,
|
# Edge case where the app dep may be on hold,
|
||||||
# cf https://forum.yunohost.org/t/migration-error-cause-of-ffsync/20675/4
|
# cf https://forum.yunohost.org/t/migration-error-cause-of-ffsync/20675/4
|
||||||
if apt-mark showhold | grep -q -w ${app_ynh_deps}
|
if apt-mark showhold | grep -q -w ${app_ynh_deps}; then
|
||||||
then
|
|
||||||
apt-mark unhold ${app_ynh_deps}
|
apt-mark unhold ${app_ynh_deps}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Remove the fake package and its dependencies if they not still used.
|
# Remove the fake package and its dependencies if they not still used.
|
||||||
# (except if dpkg doesn't know anything about the package,
|
# (except if dpkg doesn't know anything about the package,
|
||||||
# which should be symptomatic of a failed install, and we don't want bash to report an error)
|
# which should be symptomatic of a failed install, and we don't want bash to report an error)
|
||||||
if dpkg-query --show ${app_ynh_deps} &>/dev/null
|
if dpkg-query --show ${app_ynh_deps} &> /dev/null; then
|
||||||
then
|
|
||||||
_ynh_apt autoremove --purge ${app_ynh_deps}
|
_ynh_apt autoremove --purge ${app_ynh_deps}
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install packages from an extra repository properly.
|
# Install packages from an extra repository properly.
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_apt_install_dependencies_from_extra_repository --repo="repo" --package="dep1 dep2" --key=key_url
|
# usage: ynh_apt_install_dependencies_from_extra_repository --repo="repo" --package="dep1 dep2" --key=key_url
|
||||||
# | arg: -r, --repo= - Complete url of the extra repository.
|
# | arg: --repo= - Complete url of the extra repository.
|
||||||
# | arg: -p, --package= - The packages to install from this extra repository
|
# | arg: --package= - The packages to install from this extra repository
|
||||||
# | arg: -k, --key= - url to get the public key.
|
# | arg: --key= - url to get the public key.
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.8.1 or higher.
|
|
||||||
ynh_apt_install_dependencies_from_extra_repository() {
|
ynh_apt_install_dependencies_from_extra_repository() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([r]=repo= [p]=package= [k]=key=)
|
local -A args_array=([r]=repo= [p]=package= [k]=key=)
|
||||||
|
@ -213,14 +191,32 @@ ynh_apt_install_dependencies_from_extra_repository() {
|
||||||
# ===========================================
|
# ===========================================
|
||||||
|
|
||||||
# Split the repository into uri, suite and components.
|
# Split the repository into uri, suite and components.
|
||||||
repo="${repo#deb }"
|
IFS=', ' read -r -a repo_parts <<< "$repo"
|
||||||
local uri="$(echo "$repo" | awk '{ print $1 }')"
|
index=0
|
||||||
local suite="$(echo "$repo" | awk '{ print $2 }')"
|
|
||||||
local component="${repo##$uri $suite }"
|
# Remove "deb " at the beginning of the repo.
|
||||||
|
if [[ "${repo_parts[0]}" == "deb" ]]; then
|
||||||
|
index=1
|
||||||
|
fi
|
||||||
|
uri="${repo_parts[$index]}"
|
||||||
|
index=$((index + 1))
|
||||||
|
suite="${repo_parts[$index]}"
|
||||||
|
index=$((index + 1))
|
||||||
|
|
||||||
|
# Get the components
|
||||||
|
if (("${#repo_parts[@]}" > 0)); then
|
||||||
|
component="${repo_parts[*]:$index}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$key" == "trusted=yes" ]]; then
|
||||||
|
trust="[trusted=yes]"
|
||||||
|
else
|
||||||
|
trust=""
|
||||||
|
fi
|
||||||
|
|
||||||
# Add the new repo in sources.list.d
|
# Add the new repo in sources.list.d
|
||||||
mkdir --parents "/etc/apt/sources.list.d"
|
mkdir --parents "/etc/apt/sources.list.d"
|
||||||
echo "deb $uri $suite $component" > "/etc/apt/sources.list.d/$app.list"
|
echo "deb $trust $uri $suite $component" > "/etc/apt/sources.list.d/$app.list"
|
||||||
|
|
||||||
# Pin the new repo with the default priority, so it won't be used for upgrades.
|
# Pin the new repo with the default priority, so it won't be used for upgrades.
|
||||||
# Build $pin from the uri without http and any sub path
|
# Build $pin from the uri without http and any sub path
|
||||||
|
@ -235,9 +231,11 @@ Pin: origin $pin
|
||||||
Pin-Priority: 995
|
Pin-Priority: 995
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
if [ -n "$key" ] && [[ "$key" != "trusted=yes" ]]; then
|
||||||
mkdir --parents "/etc/apt/trusted.gpg.d"
|
mkdir --parents "/etc/apt/trusted.gpg.d"
|
||||||
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
||||||
wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor | tee /etc/apt/trusted.gpg.d/$name.gpg >/dev/null
|
wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor > /etc/apt/trusted.gpg.d/$app.gpg
|
||||||
|
fi
|
||||||
|
|
||||||
# Update the list of package with the new repo NB: we use -o
|
# Update the list of package with the new repo NB: we use -o
|
||||||
# Dir::Etc::sourcelist to only refresh this repo, because
|
# Dir::Etc::sourcelist to only refresh this repo, because
|
||||||
|
@ -262,13 +260,12 @@ EOF
|
||||||
ynh_safe_rm "/etc/apt/sources.list.d/$app.list"
|
ynh_safe_rm "/etc/apt/sources.list.d/$app.list"
|
||||||
ynh_safe_rm "/etc/apt/preferences.d/$app"
|
ynh_safe_rm "/etc/apt/preferences.d/$app"
|
||||||
ynh_safe_rm "/etc/apt/trusted.gpg.d/$app.gpg"
|
ynh_safe_rm "/etc/apt/trusted.gpg.d/$app.gpg"
|
||||||
ynh_apt_update
|
_ynh_apt update
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# #####################
|
||||||
#######################
|
|
||||||
# Internal misc utils #
|
# Internal misc utils #
|
||||||
#######################
|
# #####################
|
||||||
|
|
||||||
# Check if apt is free to use, or wait, until timeout.
|
# Check if apt is free to use, or wait, until timeout.
|
||||||
_ynh_wait_dpkg_free() {
|
_ynh_wait_dpkg_free() {
|
||||||
|
|
|
@ -27,13 +27,11 @@ ynh_backup() {
|
||||||
local is_data=false
|
local is_data=false
|
||||||
|
|
||||||
# If the path starts with /var/log/$app or $data_dir
|
# If the path starts with /var/log/$app or $data_dir
|
||||||
if ([[ -n "${app:-}" ]] && [[ "$target" == "/var/log/$app*" ]]) || ([[ -n "${data_dir:-}" ]] && [[ "$target" == "$data_dir*" ]])
|
if ([[ -n "${app:-}" ]] && [[ "$target" == "/var/log/$app*" ]]) || ([[ -n "${data_dir:-}" ]] && [[ "$target" == "$data_dir*" ]]); then
|
||||||
then
|
|
||||||
is_data=true
|
is_data=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "${app:-}" ]]
|
if [[ -n "${app:-}" ]]; then
|
||||||
then
|
|
||||||
local do_not_backup_data=$(ynh_app_setting_get --key=do_not_backup_data)
|
local do_not_backup_data=$(ynh_app_setting_get --key=do_not_backup_data)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -128,8 +126,6 @@ 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`
|
||||||
# otheriwse, search for a match in the csv (eg: conf/nginx.conf) and restore it into
|
# otheriwse, search for a match in the csv (eg: conf/nginx.conf) and restore it into
|
||||||
# `/etc/nginx/conf.d/$domain.d/$app.conf`
|
# `/etc/nginx/conf.d/$domain.d/$app.conf`
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_restore() {
|
ynh_restore() {
|
||||||
target="$1"
|
target="$1"
|
||||||
|
|
||||||
|
@ -137,15 +133,13 @@ ynh_restore() {
|
||||||
|
|
||||||
# If the path starts with /var/log/$app or $data_dir
|
# If the path starts with /var/log/$app or $data_dir
|
||||||
local is_data=false
|
local is_data=false
|
||||||
if ([[ -n "${app:-}" ]] && [[ "$target" == "/var/log/$app*" ]]) || ([[ -n "${data_dir:-}" ]] && [[ "$target" == "$data_dir*" ]])
|
if ([[ -n "${app:-}" ]] && [[ "$target" == "/var/log/$app*" ]]) || ([[ -n "${data_dir:-}" ]] && [[ "$target" == "$data_dir*" ]]); then
|
||||||
then
|
|
||||||
is_data=true
|
is_data=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 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 [[ "$is_data" == true ]]
|
if [[ "$is_data" == true ]]; then
|
||||||
then
|
|
||||||
ynh_print_info "Skipping $target which doesn't exists in the archive, probably because restoring from a safety-backup-before-upgrade"
|
ynh_print_info "Skipping $target which doesn't exists in the archive, probably because restoring from a safety-backup-before-upgrade"
|
||||||
# Assume it's not a big deal, we may be restoring a safety-backup-before-upgrade which doesnt contain those
|
# Assume it's not a big deal, we may be restoring a safety-backup-before-upgrade which doesnt contain those
|
||||||
return 0
|
return 0
|
||||||
|
@ -181,13 +175,13 @@ ynh_restore() {
|
||||||
else
|
else
|
||||||
mv "$archive_path" "${target}"
|
mv "$archive_path" "${target}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
_ynh_apply_default_permissions "$target"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Restore all files that were previously backuped in an app backup script
|
# Restore all files that were previously backuped in an app backup script
|
||||||
#
|
#
|
||||||
# usage: ynh_restore_everything
|
# usage: ynh_restore_everything
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_restore_everything() {
|
ynh_restore_everything() {
|
||||||
# Deduce the relative path of $YNH_CWD
|
# Deduce the relative path of $YNH_CWD
|
||||||
local REL_DIR="${YNH_CWD#$YNH_BACKUP_DIR/}"
|
local REL_DIR="${YNH_CWD#$YNH_BACKUP_DIR/}"
|
||||||
|
@ -196,7 +190,7 @@ ynh_restore_everything() {
|
||||||
# For each destination path begining by $REL_DIR
|
# For each destination path begining by $REL_DIR
|
||||||
cat ${YNH_BACKUP_CSV} | tr --delete $'\r' | grep --only-matching --no-filename --perl-regexp "^\".*\",\"$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; do
|
||||||
local ARCHIVE_PATH=$(echo "$line" | grep --only-matching --no-filename --perl-regexp "^\".*\",\"$REL_DIR\K.*(?=\"$)")
|
local ARCHIVE_PATH=$(echo "$line" | grep --only-matching --no-filename --perl-regexp "^\"\K.*(?=\",\"$REL_DIR.*\"$)")
|
||||||
ynh_restore "$ARCHIVE_PATH"
|
ynh_restore "$ARCHIVE_PATH"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
@ -211,6 +205,7 @@ _ynh_file_checksum_exists() {
|
||||||
#
|
#
|
||||||
# usage: ynh_store_file_checksum /path/to/file
|
# usage: ynh_store_file_checksum /path/to/file
|
||||||
ynh_store_file_checksum() {
|
ynh_store_file_checksum() {
|
||||||
|
set +o xtrace # set +x
|
||||||
local file=$1
|
local file=$1
|
||||||
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
||||||
|
|
||||||
|
@ -231,6 +226,7 @@ ynh_store_file_checksum() {
|
||||||
fi
|
fi
|
||||||
# Unset the variable, so it wouldn't trig a ynh_store_file_checksum without a ynh_backup_if_checksum_is_different before it.
|
# Unset the variable, so it wouldn't trig a ynh_store_file_checksum without a ynh_backup_if_checksum_is_different before it.
|
||||||
unset backup_file_checksum
|
unset backup_file_checksum
|
||||||
|
set -o xtrace # set -x
|
||||||
}
|
}
|
||||||
|
|
||||||
# Verify the checksum and backup the file if it's different
|
# Verify the checksum and backup the file if it's different
|
||||||
|
@ -240,6 +236,7 @@ ynh_store_file_checksum() {
|
||||||
# This helper is primarily meant to allow to easily backup personalised/manually
|
# This helper is primarily meant to allow to easily backup personalised/manually
|
||||||
# modified config files.
|
# modified config files.
|
||||||
ynh_backup_if_checksum_is_different() {
|
ynh_backup_if_checksum_is_different() {
|
||||||
|
set +o xtrace # set +x
|
||||||
local file=$1
|
local file=$1
|
||||||
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
||||||
local checksum_value=$(ynh_app_setting_get --key=$checksum_setting_name)
|
local checksum_value=$(ynh_app_setting_get --key=$checksum_setting_name)
|
||||||
|
@ -255,14 +252,14 @@ ynh_backup_if_checksum_is_different() {
|
||||||
echo "$backup_file_checksum" # Return the name of the backup file
|
echo "$backup_file_checksum" # Return the name of the backup file
|
||||||
if ynh_in_ci_tests; then
|
if ynh_in_ci_tests; then
|
||||||
local file_path_base64=$(echo "$file" | base64 -w0)
|
local file_path_base64=$(echo "$file" | base64 -w0)
|
||||||
if test -e /var/cache/yunohost/appconfbackup/original_${file_path_base64}
|
if test -e /var/cache/yunohost/appconfbackup/original_${file_path_base64}; then
|
||||||
then
|
|
||||||
ynh_print_warn "Diff with the original file:"
|
ynh_print_warn "Diff with the original file:"
|
||||||
diff --report-identical-files --unified --color=always /var/cache/yunohost/appconfbackup/original_${file_path_base64} $file >&2 || true
|
diff --report-identical-files --unified --color=always /var/cache/yunohost/appconfbackup/original_${file_path_base64} $file >&2 || true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
set -o xtrace # set -x
|
||||||
}
|
}
|
||||||
|
|
||||||
# Delete a file checksum from the app settings
|
# Delete a file checksum from the app settings
|
||||||
|
|
45
helpers/helpers.v2.1.d/composer
Normal file
45
helpers/helpers.v2.1.d/composer
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Install and initialize Composer in the given directory
|
||||||
|
#
|
||||||
|
# The installed version is defined by `$composer_version` which should be defined
|
||||||
|
# as global prior to calling this helper.
|
||||||
|
#
|
||||||
|
# Will use `$install_dir` as workdir unless `$composer_workdir` exists (but that shouldnt be necessary)
|
||||||
|
#
|
||||||
|
# usage: ynh_composer_install
|
||||||
|
ynh_composer_install() {
|
||||||
|
local workdir="${composer_workdir:-$install_dir}"
|
||||||
|
|
||||||
|
[[ -n "${composer_version}" ]] || ynh_die "\$composer_version should be defined before calling ynh_composer_install. (In the past, this was called \$YNH_COMPOSER_VERSION)"
|
||||||
|
|
||||||
|
[[ ! -e "$workdir/composer.phar" ]] || ynh_safe_rm $workdir/composer.phar
|
||||||
|
|
||||||
|
local composer_url="https://getcomposer.org/download/$composer_version/composer.phar"
|
||||||
|
|
||||||
|
# NB. we have to declare the var as local first,
|
||||||
|
# otherwise 'local foo=$(false) || echo 'pwet'" does'nt work
|
||||||
|
# because local always return 0 ...
|
||||||
|
local out
|
||||||
|
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
||||||
|
out=$(wget --tries 3 --no-dns-cache --timeout 900 --no-verbose --output-document=$workdir/composer.phar $composer_url 2>&1) \
|
||||||
|
|| ynh_die "$out"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute a command with Composer
|
||||||
|
#
|
||||||
|
# Will use `$install_dir` as workdir unless `$composer_workdir` exists (but that shouldnt be necessary)
|
||||||
|
#
|
||||||
|
# You may also define `composer_user=root` prior to call this helper if you
|
||||||
|
# absolutely need composer to run as root, but this is discouraged...
|
||||||
|
#
|
||||||
|
# usage: ynh_composer_exec commands
|
||||||
|
ynh_composer_exec() {
|
||||||
|
local workdir="${composer_workdir:-$install_dir}"
|
||||||
|
|
||||||
|
COMPOSER_HOME="$workdir/.composer" \
|
||||||
|
COMPOSER_MEMORY_LIMIT=-1 \
|
||||||
|
sudo -E -u "${composer_user:-$app}" \
|
||||||
|
php${php_version} "$workdir/composer.phar" $@ \
|
||||||
|
-d "$workdir" --no-interaction --no-ansi 2>&1
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ _ynh_app_config_get_one() {
|
||||||
if [[ "$bind" == "settings" ]]; then
|
if [[ "$bind" == "settings" ]]; then
|
||||||
ynh_die "File '${short_setting}' can't be stored in settings"
|
ynh_die "File '${short_setting}' can't be stored in settings"
|
||||||
fi
|
fi
|
||||||
old[$short_setting]="$(ls "$(echo $bind | sed s@__INSTALL_DIR__@${install_dir:-}@ | sed s/__APP__/$app/)" 2>/dev/null || echo YNH_NULL)"
|
old[$short_setting]="$(ls "$bind" 2> /dev/null || echo YNH_NULL)"
|
||||||
file_hash[$short_setting]="true"
|
file_hash[$short_setting]="true"
|
||||||
|
|
||||||
# Get multiline text from settings or from a full file
|
# Get multiline text from settings or from a full file
|
||||||
|
@ -32,7 +32,7 @@ _ynh_app_config_get_one() {
|
||||||
elif [[ "$bind" == *":"* ]]; then
|
elif [[ "$bind" == *":"* ]]; then
|
||||||
ynh_die "For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
|
ynh_die "For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
|
||||||
else
|
else
|
||||||
old[$short_setting]="$(cat $(echo $bind | sed s@__INSTALL_DIR__@${install_dir:-}@ | sed s/__APP__/$app/) 2>/dev/null || echo YNH_NULL)"
|
old[$short_setting]="$(cat "$bind" 2> /dev/null || echo YNH_NULL)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get value from a kind of key/value file
|
# Get value from a kind of key/value file
|
||||||
|
@ -47,7 +47,7 @@ _ynh_app_config_get_one() {
|
||||||
bind_after="$(echo "${bind_key_}" | cut -d'>' -f1)"
|
bind_after="$(echo "${bind_key_}" | cut -d'>' -f1)"
|
||||||
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
||||||
fi
|
fi
|
||||||
local bind_file="$(echo "$bind" | cut -d: -f2 | sed s@__INSTALL_DIR__@${install_dir:-}@ | sed s/__APP__/$app/)"
|
local bind_file="$(echo "$bind" | cut -d: -f2)"
|
||||||
old[$short_setting]="$(ynh_read_var_in_file --file="${bind_file}" --key="${bind_key_}" --after="${bind_after}")"
|
old[$short_setting]="$(ynh_read_var_in_file --file="${bind_file}" --key="${bind_key_}" --after="${bind_after}")"
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
@ -73,7 +73,7 @@ _ynh_app_config_apply_one() {
|
||||||
if [[ "$bind" == "settings" ]]; then
|
if [[ "$bind" == "settings" ]]; then
|
||||||
ynh_die "File '${short_setting}' can't be stored in settings"
|
ynh_die "File '${short_setting}' can't be stored in settings"
|
||||||
fi
|
fi
|
||||||
local bind_file="$(echo "$bind" | sed s@__INSTALL_DIR__@${install_dir:-}@ | sed s/__APP__/$app/)"
|
local bind_file="$bind"
|
||||||
if [[ "${!short_setting}" == "" ]]; then
|
if [[ "${!short_setting}" == "" ]]; then
|
||||||
ynh_backup_if_checksum_is_different "$bind_file"
|
ynh_backup_if_checksum_is_different "$bind_file"
|
||||||
ynh_safe_rm "$bind_file"
|
ynh_safe_rm "$bind_file"
|
||||||
|
@ -84,8 +84,7 @@ _ynh_app_config_apply_one() {
|
||||||
if [[ "${!short_setting}" != "$bind_file" ]]; then
|
if [[ "${!short_setting}" != "$bind_file" ]]; then
|
||||||
cp "${!short_setting}" "$bind_file"
|
cp "${!short_setting}" "$bind_file"
|
||||||
fi
|
fi
|
||||||
if _ynh_file_checksum_exists "$bind_file"
|
if _ynh_file_checksum_exists "$bind_file"; then
|
||||||
then
|
|
||||||
ynh_store_file_checksum "$bind_file"
|
ynh_store_file_checksum "$bind_file"
|
||||||
fi
|
fi
|
||||||
ynh_print_info "File '$bind_file' overwritten with ${!short_setting}"
|
ynh_print_info "File '$bind_file' overwritten with ${!short_setting}"
|
||||||
|
@ -101,11 +100,10 @@ _ynh_app_config_apply_one() {
|
||||||
if [[ "$bind" == *":"* ]]; then
|
if [[ "$bind" == *":"* ]]; then
|
||||||
ynh_die "For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
|
ynh_die "For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
|
||||||
fi
|
fi
|
||||||
local bind_file="$(echo "$bind" | sed s@__INSTALL_DIR__@${install_dir:-}@ | sed s/__APP__/$app/)"
|
local bind_file="$bind"
|
||||||
ynh_backup_if_checksum_is_different "$bind_file"
|
ynh_backup_if_checksum_is_different "$bind_file"
|
||||||
echo "${!short_setting}" > "$bind_file"
|
echo "${!short_setting}" > "$bind_file"
|
||||||
if _ynh_file_checksum_exists "$bind_file"
|
if _ynh_file_checksum_exists "$bind_file"; then
|
||||||
then
|
|
||||||
ynh_store_file_checksum "$bind_file"
|
ynh_store_file_checksum "$bind_file"
|
||||||
fi
|
fi
|
||||||
ynh_print_info "File '$bind_file' overwritten with the content provided in question '${short_setting}'"
|
ynh_print_info "File '$bind_file' overwritten with the content provided in question '${short_setting}'"
|
||||||
|
@ -119,12 +117,11 @@ _ynh_app_config_apply_one() {
|
||||||
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
||||||
fi
|
fi
|
||||||
bind_key_=${bind_key_:-$short_setting}
|
bind_key_=${bind_key_:-$short_setting}
|
||||||
local bind_file="$(echo "$bind" | cut -d: -f2 | sed s@__INSTALL_DIR__@${install_dir:-}@ | sed s/__APP__/$app/)"
|
local bind_file="$(echo "$bind" | cut -d: -f2)"
|
||||||
|
|
||||||
ynh_backup_if_checksum_is_different "$bind_file"
|
ynh_backup_if_checksum_is_different "$bind_file"
|
||||||
ynh_write_var_in_file --file="${bind_file}" --key="${bind_key_}" --value="${!short_setting}" --after="${bind_after}"
|
ynh_write_var_in_file --file="${bind_file}" --key="${bind_key_}" --value="${!short_setting}" --after="${bind_after}"
|
||||||
if _ynh_file_checksum_exists "$bind_file"
|
if _ynh_file_checksum_exists "$bind_file"; then
|
||||||
then
|
|
||||||
ynh_store_file_checksum "$bind_file"
|
ynh_store_file_checksum "$bind_file"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -135,60 +132,9 @@ _ynh_app_config_apply_one() {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_ynh_app_config_get() {
|
_ynh_app_config_get() {
|
||||||
# From settings
|
for line in $YNH_APP_CONFIG_PANEL_OPTIONS_TYPES_AND_BINDS; do
|
||||||
local lines
|
|
||||||
lines=$(
|
|
||||||
python3 <<EOL
|
|
||||||
import toml
|
|
||||||
from collections import OrderedDict
|
|
||||||
with open("../config_panel.toml", "r") as f:
|
|
||||||
file_content = f.read()
|
|
||||||
loaded_toml = toml.loads(file_content, _dict=OrderedDict)
|
|
||||||
|
|
||||||
for panel_name, panel in loaded_toml.items():
|
|
||||||
if not isinstance(panel, dict): continue
|
|
||||||
bind_panel = panel.get('bind')
|
|
||||||
for section_name, section in panel.items():
|
|
||||||
if not isinstance(section, dict): continue
|
|
||||||
bind_section = section.get('bind')
|
|
||||||
if not bind_section:
|
|
||||||
bind_section = bind_panel
|
|
||||||
elif bind_section[-1] == ":" and bind_panel and ":" in bind_panel:
|
|
||||||
regex, bind_panel_file = bind_panel.split(":")
|
|
||||||
if ">" in bind_section:
|
|
||||||
bind_section = bind_section + bind_panel_file
|
|
||||||
else:
|
|
||||||
bind_section = regex + bind_section + bind_panel_file
|
|
||||||
|
|
||||||
for name, param in section.items():
|
|
||||||
if not isinstance(param, dict):
|
|
||||||
continue
|
|
||||||
|
|
||||||
bind = param.get('bind')
|
|
||||||
|
|
||||||
if not bind:
|
|
||||||
if bind_section:
|
|
||||||
bind = bind_section
|
|
||||||
else:
|
|
||||||
bind = 'settings'
|
|
||||||
elif bind[-1] == ":" and bind_section and ":" in bind_section:
|
|
||||||
regex, bind_file = bind_section.split(":")
|
|
||||||
if ">" in bind:
|
|
||||||
bind = bind + bind_file
|
|
||||||
else:
|
|
||||||
bind = regex + bind + bind_file
|
|
||||||
if bind == "settings" and param.get('type', 'string') == 'file':
|
|
||||||
bind = 'null'
|
|
||||||
|
|
||||||
print('|'.join([
|
|
||||||
name,
|
|
||||||
param.get('type', 'string'),
|
|
||||||
bind
|
|
||||||
]))
|
|
||||||
EOL
|
|
||||||
)
|
|
||||||
for line in $lines; do
|
|
||||||
# Split line into short_setting, type and bind
|
# Split line into short_setting, type and bind
|
||||||
IFS='|' read short_setting type bind <<< "$line"
|
IFS='|' read short_setting type bind <<< "$line"
|
||||||
binds[${short_setting}]="$bind"
|
binds[${short_setting}]="$bind"
|
||||||
|
@ -197,7 +143,6 @@ EOL
|
||||||
formats[${short_setting}]=""
|
formats[${short_setting}]=""
|
||||||
ynh_app_config_get_one $short_setting $type $bind
|
ynh_app_config_get_one $short_setting $type $bind
|
||||||
done
|
done
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ynh_app_config_apply() {
|
_ynh_app_config_apply() {
|
||||||
|
@ -359,5 +304,6 @@ ynh_app_config_run() {
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
ynh_app_action_run $1
|
ynh_app_action_run $1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,16 @@
|
||||||
|
|
||||||
# Create a dedicated fail2ban config (jail and filter conf files)
|
# Create a dedicated fail2ban config (jail and filter conf files)
|
||||||
#
|
#
|
||||||
# usage 1: ynh_config_add_fail2ban --logpath=log_file --failregex=filter
|
# usage: ynh_config_add_fail2ban --logpath=log_file --failregex=filter
|
||||||
# | arg: -l, --logpath= - Log file to be checked by fail2ban
|
# | arg: --logpath= - Log file to be checked by fail2ban
|
||||||
# | arg: -r, --failregex= - Failregex to be looked for by fail2ban
|
# | arg: --failregex= - Failregex to be looked for by fail2ban
|
||||||
#
|
#
|
||||||
# usage 2: ynh_config_add_fail2ban
|
# If --logpath / --failregex are provided, the helper will generate the appropriate conf using these.
|
||||||
# | arg: -t, --use_template - Use this helper in template mode
|
|
||||||
#
|
#
|
||||||
# This will use a template in `../conf/f2b_jail.conf` and `../conf/f2b_filter.conf`
|
# Otherwise, it will assume that the app provided templates, namely
|
||||||
# See the documentation of `ynh_config_add` for a description of the template
|
# `../conf/f2b_jail.conf` and `../conf/f2b_filter.conf`
|
||||||
# format and how placeholders are replaced with actual variables.
|
|
||||||
#
|
#
|
||||||
# Generally your template will look like that by example (for synapse):
|
# They will typically look like (for example here for synapse):
|
||||||
# ```
|
# ```
|
||||||
# f2b_jail.conf:
|
# f2b_jail.conf:
|
||||||
# [__APP__]
|
# [__APP__]
|
||||||
|
@ -38,9 +36,7 @@
|
||||||
# ignoreregex =
|
# ignoreregex =
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
# -----------------------------------------------------------------------------
|
# ##### Regarding the the `failregex` option:
|
||||||
#
|
|
||||||
# Note about the "failregex" option:
|
|
||||||
#
|
#
|
||||||
# regex to match the password failure messages in the logfile. The host must be
|
# regex to match the password failure messages in the logfile. The host must be
|
||||||
# matched by a group named "`host`". The tag "`<HOST>`" can be used for standard
|
# matched by a group named "`host`". The tag "`<HOST>`" can be used for standard
|
||||||
|
@ -53,8 +49,6 @@
|
||||||
# ```
|
# ```
|
||||||
# fail2ban-regex /var/log/YOUR_LOG_FILE_PATH /etc/fail2ban/filter.d/YOUR_APP.conf
|
# fail2ban-regex /var/log/YOUR_LOG_FILE_PATH /etc/fail2ban/filter.d/YOUR_APP.conf
|
||||||
# ```
|
# ```
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_config_add_fail2ban() {
|
ynh_config_add_fail2ban() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([l]=logpath= [r]=failregex=)
|
local -A args_array=([l]=logpath= [r]=failregex=)
|
||||||
|
@ -117,8 +111,6 @@ ignoreregex =
|
||||||
# Remove the dedicated fail2ban config (jail and filter conf files)
|
# Remove the dedicated fail2ban config (jail and filter conf files)
|
||||||
#
|
#
|
||||||
# usage: ynh_config_remove_fail2ban
|
# usage: ynh_config_remove_fail2ban
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
|
||||||
ynh_config_remove_fail2ban() {
|
ynh_config_remove_fail2ban() {
|
||||||
ynh_safe_rm "/etc/fail2ban/jail.d/$app.conf"
|
ynh_safe_rm "/etc/fail2ban/jail.d/$app.conf"
|
||||||
ynh_safe_rm "/etc/fail2ban/filter.d/$app.conf"
|
ynh_safe_rm "/etc/fail2ban/filter.d/$app.conf"
|
||||||
|
|
|
@ -40,17 +40,18 @@
|
||||||
# If there's many values for an option, -f /final /path, the value will be separated by a ';' $finalpath=/final;/path
|
# If there's many values for an option, -f /final /path, the value will be separated by a ';' $finalpath=/final;/path
|
||||||
# For an option without value, like --user in the example, the helper can be called only with --user or -u. $user will then get the value 1.
|
# For an option without value, like --user in the example, the helper can be called only with --user or -u. $user will then get the value 1.
|
||||||
#
|
#
|
||||||
# To keep a retrocompatibility, a package can still call a helper, using getopts, with positional arguments.
|
|
||||||
# The "legacy mode" will manage the positional arguments and fill the variable in the same order than they are given in $args_array.
|
|
||||||
# e.g. for `my_helper "val1" val2`, arg1 will be filled with val1, and arg2 with val2.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.2.2 or higher.
|
|
||||||
ynh_handle_getopts_args() {
|
ynh_handle_getopts_args() {
|
||||||
|
# Trick to only re-enable debugging if it was set before
|
||||||
|
local xtrace_enable=$(set +o | grep xtrace)
|
||||||
|
|
||||||
# Manage arguments only if there's some provided
|
# Manage arguments only if there's some provided
|
||||||
set +o xtrace # set +x
|
set +o xtrace # set +x
|
||||||
if [ $# -eq 0 ]; then
|
if [ $# -eq 0 ]; then
|
||||||
set -o xtrace # set -x
|
eval "$xtrace_enable"
|
||||||
return
|
return
|
||||||
|
# Validate that the first char is - because it should be something like --option=value or -o ...
|
||||||
|
elif [[ "${1:0:1}" != "-" ]]; then
|
||||||
|
ynh_die "It looks like you called the helper using positional arguments instead of keyword arguments ?"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Store arguments in an array to keep each argument separated
|
# Store arguments in an array to keep each argument separated
|
||||||
|
@ -100,9 +101,9 @@ ynh_handle_getopts_args() {
|
||||||
getopts ":$getopts_parameters" parameter || true
|
getopts ":$getopts_parameters" parameter || true
|
||||||
|
|
||||||
if [ "$parameter" = "?" ]; then
|
if [ "$parameter" = "?" ]; then
|
||||||
ynh_die "Invalid argument: -${OPTARG:-}"
|
ynh_die "Invalid argument: ${1:-}"
|
||||||
elif [ "$parameter" = ":" ]; then
|
elif [ "$parameter" = ":" ]; then
|
||||||
ynh_die "-$OPTARG parameter requires an argument."
|
ynh_die "${1:-} 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
|
||||||
|
@ -181,5 +182,5 @@ ynh_handle_getopts_args() {
|
||||||
# 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[@]}"
|
||||||
|
|
||||||
set -o xtrace # set -x
|
eval "$xtrace_enable"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,17 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
ynh_go_try_bash_extension() {
|
readonly GOENV_INSTALL_DIR="/opt/goenv"
|
||||||
if [ -x src/configure ]; then
|
|
||||||
src/configure && make -C src || {
|
|
||||||
ynh_print_info "Optional bash extension failed to build, but things will still work normally."
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
goenv_install_dir="/opt/goenv"
|
|
||||||
go_version_path="$goenv_install_dir/versions"
|
|
||||||
# goenv_ROOT is the directory of goenv, it needs to be loaded as a environment variable.
|
# goenv_ROOT is the directory of goenv, it needs to be loaded as a environment variable.
|
||||||
export GOENV_ROOT="$goenv_install_dir"
|
export GOENV_ROOT="$GOENV_INSTALL_DIR"
|
||||||
|
|
||||||
_ynh_load_go_in_path_and_other_tweaks() {
|
_ynh_load_go_in_path_and_other_tweaks() {
|
||||||
|
|
||||||
# Get the absolute path of this version of go
|
# Get the absolute path of this version of go
|
||||||
local go_path="$go_version_path/$app/bin"
|
go_dir="$GOENV_INSTALL_DIR/versions/$app/bin"
|
||||||
|
|
||||||
# Load the path of this version of go in $PATH
|
# Load the path of this version of go in $PATH
|
||||||
if [[ :$PATH: != *":$go_path"* ]]; then
|
if [[ :$PATH: != *":$go_dir"* ]]; then
|
||||||
PATH="$go_path:$PATH"
|
PATH="$go_dir:$PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Export PATH such that it's available through sudo -E / ynh_exec_as $app
|
# Export PATH such that it's available through sudo -E / ynh_exec_as $app
|
||||||
|
@ -32,31 +23,28 @@ _ynh_load_go_in_path_and_other_tweaks() {
|
||||||
|
|
||||||
# Sets the local application-specific go version
|
# Sets the local application-specific go version
|
||||||
pushd ${install_dir}
|
pushd ${install_dir}
|
||||||
$goenv_install_dir/bin/goenv local $go_version
|
$GOENV_INSTALL_DIR/bin/goenv local $go_version
|
||||||
popd
|
popd
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install a specific version of Go using goenv
|
# Install a specific version of Go using goenv
|
||||||
#
|
#
|
||||||
# The installed version is defined by $nodejs_version which should be defined as global prior to calling this helper
|
# The installed version is defined by `$go_version` which should be defined as global prior to calling this helper
|
||||||
#
|
|
||||||
# This helper creates a /etc/profile.d/goenv.sh that configures PATH environment for goenv
|
|
||||||
# for every LOGIN user, hence your user must have a defined shell (as opposed to /usr/sbin/nologin)
|
|
||||||
#
|
|
||||||
# Don't forget to execute go-dependent command in a login environment
|
|
||||||
# (e.g. sudo --login option)
|
|
||||||
# When not possible (e.g. in systemd service definition), please use direct path
|
|
||||||
# to goenv shims (e.g. $goenv_ROOT/shims/bundle)
|
|
||||||
#
|
#
|
||||||
# usage: ynh_go_install
|
# usage: ynh_go_install
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.2.2 or higher.
|
# The helper adds the appropriate, specific version of go to the `$PATH` variable (which
|
||||||
|
# is preserved when calling `ynh_exec_as_app`). Also defines:
|
||||||
|
# - `$path_with_go` (the value of the modified `$PATH`, but you dont really need it?)
|
||||||
|
# - `$go_dir` (the directory containing the specific go version)
|
||||||
|
#
|
||||||
|
# This helper also creates a /etc/profile.d/goenv.sh that configures PATH environment for goenv
|
||||||
ynh_go_install() {
|
ynh_go_install() {
|
||||||
|
|
||||||
[[ -n "${go_version:-}" ]] || ynh_die "\$go_version should be defined prior to calling ynh_go_install"
|
[[ -n "${go_version:-}" ]] || ynh_die "\$go_version should be defined prior to calling ynh_go_install"
|
||||||
|
|
||||||
# Load goenv path in PATH
|
# Load goenv path in PATH
|
||||||
local CLEAR_PATH="$goenv_install_dir/bin:$PATH"
|
local CLEAR_PATH="$GOENV_INSTALL_DIR/bin:$PATH"
|
||||||
|
|
||||||
# Remove /usr/local/bin in PATH in case of Go prior installation
|
# Remove /usr/local/bin in PATH in case of Go prior installation
|
||||||
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
||||||
|
@ -65,9 +53,9 @@ ynh_go_install () {
|
||||||
test -x /usr/bin/go && mv /usr/bin/go /usr/bin/go_goenv
|
test -x /usr/bin/go && mv /usr/bin/go /usr/bin/go_goenv
|
||||||
|
|
||||||
# Install or update goenv
|
# Install or update goenv
|
||||||
mkdir -p $goenv_install_dir
|
mkdir -p $GOENV_INSTALL_DIR
|
||||||
pushd "$goenv_install_dir"
|
pushd "$GOENV_INSTALL_DIR"
|
||||||
if ! [ -x "$goenv_install_dir/bin/goenv" ]; then
|
if ! [ -x "$GOENV_INSTALL_DIR/bin/goenv" ]; then
|
||||||
ynh_print_info "Downloading goenv..."
|
ynh_print_info "Downloading goenv..."
|
||||||
git init -q
|
git init -q
|
||||||
git remote add origin https://github.com/syndbg/goenv.git
|
git remote add origin https://github.com/syndbg/goenv.git
|
||||||
|
@ -77,14 +65,14 @@ ynh_go_install () {
|
||||||
git fetch -q --tags --prune origin
|
git fetch -q --tags --prune origin
|
||||||
local git_latest_tag=$(git describe --tags "$(git rev-list --tags --max-count=1)")
|
local git_latest_tag=$(git describe --tags "$(git rev-list --tags --max-count=1)")
|
||||||
git checkout -q "$git_latest_tag"
|
git checkout -q "$git_latest_tag"
|
||||||
ynh_go_try_bash_extension
|
_ynh_go_try_bash_extension
|
||||||
goenv=$goenv_install_dir/bin/goenv
|
goenv=$GOENV_INSTALL_DIR/bin/goenv
|
||||||
popd
|
popd
|
||||||
|
|
||||||
# Install or update xxenv-latest
|
# Install or update xxenv-latest
|
||||||
mkdir -p "$goenv_install_dir/plugins/xxenv-latest"
|
mkdir -p "$GOENV_INSTALL_DIR/plugins/xxenv-latest"
|
||||||
pushd "$goenv_install_dir/plugins/xxenv-latest"
|
pushd "$GOENV_INSTALL_DIR/plugins/xxenv-latest"
|
||||||
if ! [ -x "$goenv_install_dir/plugins/xxenv-latest/bin/goenv-latest" ]; then
|
if ! [ -x "$GOENV_INSTALL_DIR/plugins/xxenv-latest/bin/goenv-latest" ]; then
|
||||||
ynh_print_info "Downloading xxenv-latest..."
|
ynh_print_info "Downloading xxenv-latest..."
|
||||||
git init -q
|
git init -q
|
||||||
git remote add origin https://github.com/momo-lab/xxenv-latest.git
|
git remote add origin https://github.com/momo-lab/xxenv-latest.git
|
||||||
|
@ -97,10 +85,10 @@ ynh_go_install () {
|
||||||
popd
|
popd
|
||||||
|
|
||||||
# Enable caching
|
# Enable caching
|
||||||
mkdir -p "${goenv_install_dir}/cache"
|
mkdir -p "${GOENV_INSTALL_DIR}/cache"
|
||||||
|
|
||||||
# Create shims directory if needed
|
# Create shims directory if needed
|
||||||
mkdir -p "${goenv_install_dir}/shims"
|
mkdir -p "${GOENV_INSTALL_DIR}/shims"
|
||||||
|
|
||||||
# Restore /usr/local/bin in PATH
|
# Restore /usr/local/bin in PATH
|
||||||
PATH=$CLEAR_PATH
|
PATH=$CLEAR_PATH
|
||||||
|
@ -109,7 +97,7 @@ ynh_go_install () {
|
||||||
test -x /usr/bin/go_goenv && mv /usr/bin/go_goenv /usr/bin/go
|
test -x /usr/bin/go_goenv && mv /usr/bin/go_goenv /usr/bin/go
|
||||||
|
|
||||||
# Install the requested version of Go
|
# Install the requested version of Go
|
||||||
local final_go_version=$(goenv latest --print "$go_version")
|
local final_go_version=$("$GOENV_INSTALL_DIR/plugins/xxenv-latest/bin/goenv-latest" --print "$go_version")
|
||||||
ynh_print_info "Installation of Go-$final_go_version"
|
ynh_print_info "Installation of Go-$final_go_version"
|
||||||
goenv install --quiet --skip-existing "$final_go_version" 2>&1
|
goenv install --quiet --skip-existing "$final_go_version" 2>&1
|
||||||
|
|
||||||
|
@ -122,8 +110,8 @@ ynh_go_install () {
|
||||||
|
|
||||||
# Set environment for Go users
|
# Set environment for Go users
|
||||||
echo "#goenv
|
echo "#goenv
|
||||||
export GOENV_ROOT=$goenv_install_dir
|
export GOENV_ROOT=$GOENV_INSTALL_DIR
|
||||||
export PATH=\"$goenv_install_dir/bin:$PATH\"
|
export PATH=\"$GOENV_INSTALL_DIR/bin:$PATH\"
|
||||||
eval \"\$(goenv init -)\"
|
eval \"\$(goenv init -)\"
|
||||||
#goenv" > /etc/profile.d/goenv.sh
|
#goenv" > /etc/profile.d/goenv.sh
|
||||||
|
|
||||||
|
@ -142,7 +130,7 @@ ynh_go_remove () {
|
||||||
local go_version=$(ynh_app_setting_get --key="go_version")
|
local go_version=$(ynh_app_setting_get --key="go_version")
|
||||||
|
|
||||||
# Load goenv path in PATH
|
# Load goenv path in PATH
|
||||||
local CLEAR_PATH="$goenv_install_dir/bin:$PATH"
|
local CLEAR_PATH="$GOENV_INSTALL_DIR/bin:$PATH"
|
||||||
|
|
||||||
# Remove /usr/local/bin in PATH in case of Go prior installation
|
# Remove /usr/local/bin in PATH in case of Go prior installation
|
||||||
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
||||||
|
@ -156,6 +144,8 @@ ynh_go_remove () {
|
||||||
|
|
||||||
# Remove no more needed versions of Go used by the app.
|
# Remove no more needed versions of Go used by the app.
|
||||||
#
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
# This helper will check what Go version are no more required,
|
# This helper will check what Go version are no more required,
|
||||||
# and uninstall them
|
# and uninstall them
|
||||||
# If no app uses Go, goenv will be also removed.
|
# If no app uses Go, goenv will be also removed.
|
||||||
|
@ -166,32 +156,35 @@ _ynh_go_cleanup () {
|
||||||
# List required Go versions
|
# List required Go versions
|
||||||
local installed_apps=$(yunohost app list --output-as json --quiet | jq -r .apps[].id)
|
local installed_apps=$(yunohost app list --output-as json --quiet | jq -r .apps[].id)
|
||||||
local required_go_versions=""
|
local required_go_versions=""
|
||||||
for installed_app in $installed_apps
|
for installed_app in $installed_apps; do
|
||||||
do
|
|
||||||
local installed_app_go_version=$(ynh_app_setting_get --app=$installed_app --key="go_version")
|
local installed_app_go_version=$(ynh_app_setting_get --app=$installed_app --key="go_version")
|
||||||
if [[ $installed_app_go_version ]]
|
if [[ $installed_app_go_version ]]; then
|
||||||
then
|
|
||||||
required_go_versions="${installed_app_go_version}\n${required_go_versions}"
|
required_go_versions="${installed_app_go_version}\n${required_go_versions}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Remove no more needed Go versions
|
# Remove no more needed Go versions
|
||||||
local installed_go_versions=$(goenv versions --bare --skip-aliases | grep -Ev '/')
|
local installed_go_versions=$(goenv versions --bare --skip-aliases | grep -Ev '/')
|
||||||
for installed_go_version in $installed_go_versions
|
for installed_go_version in $installed_go_versions; do
|
||||||
do
|
if ! $(echo ${required_go_versions} | grep "${installed_go_version}" 1> /dev/null 2>&1); then
|
||||||
if ! `echo ${required_go_versions} | grep "${installed_go_version}" 1>/dev/null 2>&1`
|
|
||||||
then
|
|
||||||
ynh_print_info "Removing of Go-$installed_go_version"
|
ynh_print_info "Removing of Go-$installed_go_version"
|
||||||
$goenv_install_dir/bin/goenv uninstall --force "$installed_go_version"
|
$GOENV_INSTALL_DIR/bin/goenv uninstall --force "$installed_go_version"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# If none Go version is required
|
# If none Go version is required
|
||||||
if [[ ! $required_go_versions ]]
|
if [[ ! $required_go_versions ]]; then
|
||||||
then
|
|
||||||
# Remove goenv environment configuration
|
# Remove goenv environment configuration
|
||||||
ynh_print_info "Removing of goenv"
|
ynh_print_info "Removing of goenv"
|
||||||
ynh_safe_rm "$goenv_install_dir"
|
ynh_safe_rm "$GOENV_INSTALL_DIR"
|
||||||
ynh_safe_rm "/etc/profile.d/goenv.sh"
|
ynh_safe_rm "/etc/profile.d/goenv.sh"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ynh_go_try_bash_extension() {
|
||||||
|
if [ -x src/configure ]; then
|
||||||
|
src/configure && make -C src || {
|
||||||
|
ynh_print_info "Optional bash extension failed to build, but things will still work normally."
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,13 @@
|
||||||
#
|
#
|
||||||
# usage: ynh_die "Some message"
|
# usage: ynh_die "Some message"
|
||||||
ynh_die() {
|
ynh_die() {
|
||||||
echo "$1" 1>&2
|
set +o xtrace # set +x
|
||||||
|
if [[ -n "${1:-}" ]]; then
|
||||||
|
if [[ -n "${YNH_STDRETURN:-}" ]]; then
|
||||||
|
python3 -c 'import yaml, sys; print(yaml.dump({"error": sys.stdin.read()}))' <<< "${1:-}" >> "$YNH_STDRETURN"
|
||||||
|
fi
|
||||||
|
echo "${1:-}" 1>&2
|
||||||
|
fi
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +44,6 @@ ynh_hide_warnings() {
|
||||||
# | arg: command - command to execute
|
# | arg: command - command to execute
|
||||||
#
|
#
|
||||||
# Note that you should NOT quote the command but only prefix it with ynh_exec_and_print_stderr_only_if_error
|
# Note that you should NOT quote the command but only prefix it with ynh_exec_and_print_stderr_only_if_error
|
||||||
#
|
|
||||||
# Requires YunoHost version 11.2 or higher.
|
|
||||||
ynh_exec_and_print_stderr_only_if_error() {
|
ynh_exec_and_print_stderr_only_if_error() {
|
||||||
logfile="$(mktemp)"
|
logfile="$(mktemp)"
|
||||||
rc=0
|
rc=0
|
||||||
|
@ -56,8 +60,6 @@ ynh_exec_and_print_stderr_only_if_error() {
|
||||||
# (to be used by special hooks like app config panel and core diagnosis)
|
# (to be used by special hooks like app config panel and core diagnosis)
|
||||||
#
|
#
|
||||||
# usage: ynh_return somedata
|
# usage: ynh_return somedata
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.6.0 or higher.
|
|
||||||
ynh_return() {
|
ynh_return() {
|
||||||
echo "$1" >> "$YNH_STDRETURN"
|
echo "$1" >> "$YNH_STDRETURN"
|
||||||
}
|
}
|
||||||
|
@ -76,8 +78,6 @@ progress_string0="...................."
|
||||||
# Print a progress bar showing the progression of an app script
|
# Print a progress bar showing the progression of an app script
|
||||||
#
|
#
|
||||||
# usage: ynh_script_progression "Some message"
|
# usage: ynh_script_progression "Some message"
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
|
||||||
ynh_script_progression() {
|
ynh_script_progression() {
|
||||||
set +o xtrace # set +x
|
set +o xtrace # set +x
|
||||||
|
|
||||||
|
@ -103,8 +103,7 @@ ynh_script_progression() {
|
||||||
local expected_progression="$((($increment_progression + 1) * $progress_scale / $max_progression - $effective_progression))"
|
local expected_progression="$((($increment_progression + 1) * $progress_scale / $max_progression - $effective_progression))"
|
||||||
|
|
||||||
# Hack for the "--last" message
|
# Hack for the "--last" message
|
||||||
if grep -qw 'completed' <<< "$1";
|
if grep -qw 'completed' <<< "$1"; then
|
||||||
then
|
|
||||||
effective_progression=$progress_scale
|
effective_progression=$progress_scale
|
||||||
expected_progression=0
|
expected_progression=0
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -10,11 +10,9 @@ FIRST_CALL_TO_LOGROTATE="true"
|
||||||
#
|
#
|
||||||
# The configuration is autogenerated by YunoHost
|
# The configuration is autogenerated by YunoHost
|
||||||
# (ie it doesnt come from a specific app template like nginx or systemd conf)
|
# (ie it doesnt come from a specific app template like nginx or systemd conf)
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_config_add_logrotate() {
|
ynh_config_add_logrotate() {
|
||||||
|
|
||||||
logfile="$1"
|
local logfile="${1:-}"
|
||||||
|
|
||||||
set -o noglob
|
set -o noglob
|
||||||
if [[ -z "$logfile" ]]; then
|
if [[ -z "$logfile" ]]; then
|
||||||
|
@ -24,11 +22,12 @@ ynh_config_add_logrotate() {
|
||||||
fi
|
fi
|
||||||
set +o noglob
|
set +o noglob
|
||||||
|
|
||||||
for stuff in $logfile
|
for stuff in $logfile; do
|
||||||
do
|
|
||||||
mkdir --parents $(dirname "$stuff")
|
|
||||||
# Make sure the permissions of the parent dir are correct (otherwise the config file could be ignored and the corresponding logs never rotated)
|
# Make sure the permissions of the parent dir are correct (otherwise the config file could be ignored and the corresponding logs never rotated)
|
||||||
chmod 750 $(dirname "$stuff")
|
local dir=$(dirname "$stuff")
|
||||||
|
mkdir --parents $dir
|
||||||
|
chmod 750 $dir
|
||||||
|
chown $app:$app $dir
|
||||||
done
|
done
|
||||||
|
|
||||||
local tempconf="$(mktemp)"
|
local tempconf="$(mktemp)"
|
||||||
|
@ -53,8 +52,7 @@ $logfile {
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if [[ "$FIRST_CALL_TO_LOGROTATE" == "true" ]]
|
if [[ "$FIRST_CALL_TO_LOGROTATE" == "true" ]]; then
|
||||||
then
|
|
||||||
cat $tempconf > /etc/logrotate.d/$app
|
cat $tempconf > /etc/logrotate.d/$app
|
||||||
else
|
else
|
||||||
cat $tempconf >> /etc/logrotate.d/$app
|
cat $tempconf >> /etc/logrotate.d/$app
|
||||||
|
@ -67,9 +65,7 @@ EOF
|
||||||
|
|
||||||
# Remove the app's logrotate config.
|
# Remove the app's logrotate config.
|
||||||
#
|
#
|
||||||
# usage: ynh_remove_logrotate
|
# usage:ynh_config_remove_logrotate
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_config_remove_logrotate() {
|
ynh_config_remove_logrotate() {
|
||||||
if [ -e "/etc/logrotate.d/$app" ]; then
|
if [ -e "/etc/logrotate.d/$app" ]; then
|
||||||
rm "/etc/logrotate.d/$app"
|
rm "/etc/logrotate.d/$app"
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
# example: ynh_mongo_exec --command="db.getMongo().getDBNames().indexOf(\"wekan\")"
|
# example: ynh_mongo_exec --command="db.getMongo().getDBNames().indexOf(\"wekan\")"
|
||||||
#
|
#
|
||||||
# usage: ynh_mongo_exec [--database=database] --command="command"
|
# usage: ynh_mongo_exec [--database=database] --command="command"
|
||||||
# | arg: -d, --database= - The database to connect to
|
# | arg: --database= - The database to connect to
|
||||||
# | arg: -c, --command= - The command to evaluate
|
# | arg: --command= - The command to evaluate
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
ynh_mongo_exec() {
|
ynh_mongo_exec() {
|
||||||
|
@ -19,8 +19,7 @@ ynh_mongo_exec() {
|
||||||
database="${database:-}"
|
database="${database:-}"
|
||||||
# ===========================================
|
# ===========================================
|
||||||
|
|
||||||
if [ -n "$database" ]
|
if [ -n "$database" ]; then
|
||||||
then
|
|
||||||
mongosh --quiet << EOF
|
mongosh --quiet << EOF
|
||||||
use $database
|
use $database
|
||||||
${command}
|
${command}
|
||||||
|
@ -39,7 +38,7 @@ EOF
|
||||||
# consider using ynh_mongo_remove_db instead.
|
# consider using ynh_mongo_remove_db instead.
|
||||||
#
|
#
|
||||||
# usage: ynh_mongo_drop_db --database=database
|
# usage: ynh_mongo_drop_db --database=database
|
||||||
# | arg: -d, --database= - The database name to drop
|
# | arg: --database= - The database name to drop
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
ynh_mongo_drop_db() {
|
ynh_mongo_drop_db() {
|
||||||
|
@ -57,7 +56,7 @@ ynh_mongo_drop_db() {
|
||||||
# example: ynh_mongo_dump_db --database=wekan > ./dump.bson
|
# example: ynh_mongo_dump_db --database=wekan > ./dump.bson
|
||||||
#
|
#
|
||||||
# usage: ynh_mongo_dump_db --database=database
|
# usage: ynh_mongo_dump_db --database=database
|
||||||
# | arg: -d, --database= - The database name to dump
|
# | arg: --database= - The database name to dump
|
||||||
# | ret: the mongodump output
|
# | ret: the mongodump output
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -76,9 +75,9 @@ ynh_mongo_dump_db() {
|
||||||
# [internal]
|
# [internal]
|
||||||
#
|
#
|
||||||
# usage: ynh_mongo_create_user --db_user=user --db_pwd=pwd --db_name=name
|
# usage: ynh_mongo_create_user --db_user=user --db_pwd=pwd --db_name=name
|
||||||
# | arg: -u, --db_user= - The user name to create
|
# | arg: --db_user= - The user name to create
|
||||||
# | arg: -p, --db_pwd= - The password to identify user by
|
# | arg: --db_pwd= - The password to identify user by
|
||||||
# | arg: -n, --db_name= - Name of the database to grant privilegies
|
# | arg: --db_name= - Name of the database to grant privilegies
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
ynh_mongo_create_user() {
|
ynh_mongo_create_user() {
|
||||||
|
@ -100,7 +99,7 @@ ynh_mongo_create_user() {
|
||||||
# Check if a mongo database exists
|
# Check if a mongo database exists
|
||||||
#
|
#
|
||||||
# usage: ynh_mongo_database_exists --database=database
|
# usage: ynh_mongo_database_exists --database=database
|
||||||
# | arg: -d, --database= - The database for which to check existence
|
# | arg: --database= - The database for which to check existence
|
||||||
# | exit: Return 1 if the database doesn't exist, 0 otherwise
|
# | exit: Return 1 if the database doesn't exist, 0 otherwise
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -111,8 +110,7 @@ ynh_mongo_database_exists() {
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
# ===========================================
|
# ===========================================
|
||||||
|
|
||||||
if [ $(ynh_mongo_exec --command='db.getMongo().getDBNames().indexOf("'${database}'")') -lt 0 ]
|
if [ $(ynh_mongo_exec --command='db.getMongo().getDBNames().indexOf("'${database}'")') -lt 0 ]; then
|
||||||
then
|
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
|
@ -124,7 +122,7 @@ ynh_mongo_database_exists() {
|
||||||
# example: ynh_mongo_restore_db --database=wekan < ./dump.bson
|
# example: ynh_mongo_restore_db --database=wekan < ./dump.bson
|
||||||
#
|
#
|
||||||
# usage: ynh_mongo_restore_db --database=database
|
# usage: ynh_mongo_restore_db --database=database
|
||||||
# | arg: -d, --database= - The database name to restore
|
# | arg: --database= - The database name to restore
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
ynh_mongo_restore_db() {
|
ynh_mongo_restore_db() {
|
||||||
|
@ -142,8 +140,8 @@ ynh_mongo_restore_db() {
|
||||||
# [internal]
|
# [internal]
|
||||||
#
|
#
|
||||||
# usage: ynh_mongo_drop_user --db_user=user --db_name=name
|
# usage: ynh_mongo_drop_user --db_user=user --db_name=name
|
||||||
# | arg: -u, --db_user= - The user to drop
|
# | arg: --db_user= - The user to drop
|
||||||
# | arg: -n, --db_name= - Name of the database
|
# | arg: --db_name= - Name of the database
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
ynh_mongo_drop_user() {
|
ynh_mongo_drop_user() {
|
||||||
|
@ -160,9 +158,9 @@ ynh_mongo_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_mongo_setup_db --db_user=user --db_name=name [--db_pwd=pwd]
|
# usage: ynh_mongo_setup_db --db_user=user --db_name=name [--db_pwd=pwd]
|
||||||
# | arg: -u, --db_user= - Owner of the database
|
# | arg: --db_user= - Owner of the database
|
||||||
# | arg: -n, --db_name= - Name of the database
|
# | arg: --db_name= - Name of the database
|
||||||
# | arg: -p, --db_pwd= - Password of the database. If not provided, a password will be generated
|
# | arg: --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 "mongopwd" into the app settings.
|
# It will also be stored as "mongopwd" into the app settings.
|
||||||
|
@ -191,8 +189,8 @@ ynh_mongo_setup_db() {
|
||||||
# Remove a database if it exists, and the associated user
|
# Remove a database if it exists, and the associated user
|
||||||
#
|
#
|
||||||
# usage: ynh_mongo_remove_db --db_user=user --db_name=name
|
# usage: ynh_mongo_remove_db --db_user=user --db_name=name
|
||||||
# | arg: -u, --db_user= - Owner of the database
|
# | arg: --db_user= - Owner of the database
|
||||||
# | arg: -n, --db_name= - Name of the database
|
# | arg: --db_name= - Name of the database
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
ynh_mongo_remove_db() {
|
ynh_mongo_remove_db() {
|
||||||
|
@ -226,7 +224,7 @@ ynh_install_mongo() {
|
||||||
ynh_print_info "Installing MongoDB Community Edition ..."
|
ynh_print_info "Installing MongoDB Community Edition ..."
|
||||||
local mongo_debian_release=$YNH_DEBIAN_VERSION
|
local mongo_debian_release=$YNH_DEBIAN_VERSION
|
||||||
|
|
||||||
if [[ $(cat /proc/cpuinfo) != *"avx"* && "$mongo_version" != "4.4" ]]; then
|
if [[ "$(grep '^flags' /proc/cpuinfo | uniq)" != *"avx"* && "$mongo_version" != "4.4" ]]; then
|
||||||
ynh_print_warn "Installing Mongo 4.4 as $mongo_version is not compatible with your cpu (see https://docs.mongodb.com/manual/administration/production-notes/#x86_64)."
|
ynh_print_warn "Installing Mongo 4.4 as $mongo_version is not compatible with your cpu (see https://docs.mongodb.com/manual/administration/production-notes/#x86_64)."
|
||||||
mongo_version="4.4"
|
mongo_version="4.4"
|
||||||
fi
|
fi
|
||||||
|
@ -235,7 +233,10 @@ ynh_install_mongo() {
|
||||||
mongo_debian_release=buster
|
mongo_debian_release=buster
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ynh_install_extra_app_dependencies --repo="deb http://repo.mongodb.org/apt/debian $mongo_debian_release/mongodb-org/$mongo_version main" --package="mongodb-org mongodb-org-server mongodb-org-tools mongodb-mongosh" --key="https://www.mongodb.org/static/pgp/server-$mongo_version.asc"
|
ynh_apt_install_dependencies_from_extra_repository \
|
||||||
|
--repo="deb http://repo.mongodb.org/apt/debian $mongo_debian_release/mongodb-org/$mongo_version main" \
|
||||||
|
--package="mongodb-org mongodb-org-server mongodb-org-tools mongodb-mongosh" \
|
||||||
|
--key="https://www.mongodb.org/static/pgp/server-$mongo_version.asc"
|
||||||
mongodb_servicename=mongod
|
mongodb_servicename=mongod
|
||||||
|
|
||||||
# Make sure MongoDB is started and enabled
|
# Make sure MongoDB is started and enabled
|
||||||
|
@ -259,8 +260,7 @@ ynh_install_mongo() {
|
||||||
#
|
#
|
||||||
ynh_remove_mongo() {
|
ynh_remove_mongo() {
|
||||||
# Only remove the mongodb service if it is not installed.
|
# Only remove the mongodb service if it is not installed.
|
||||||
if ! _ynh_apt_package_is_installed "mongodb*"
|
if ! _ynh_apt_package_is_installed "mongodb*"; then
|
||||||
then
|
|
||||||
ynh_print_info "Removing MongoDB service..."
|
ynh_print_info "Removing MongoDB service..."
|
||||||
mongodb_servicename=mongod
|
mongodb_servicename=mongod
|
||||||
# Remove the mongodb service
|
# Remove the mongodb service
|
||||||
|
|
|
@ -6,8 +6,6 @@ readonly MEDIA_DIRECTORY=/home/yunohost.multimedia
|
||||||
# Initialize the multimedia directory system
|
# Initialize the multimedia directory system
|
||||||
#
|
#
|
||||||
# usage: ynh_multimedia_build_main_dir
|
# usage: ynh_multimedia_build_main_dir
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.2 or higher.
|
|
||||||
ynh_multimedia_build_main_dir() {
|
ynh_multimedia_build_main_dir() {
|
||||||
|
|
||||||
## Création du groupe multimedia
|
## Création du groupe multimedia
|
||||||
|
@ -55,12 +53,10 @@ ynh_multimedia_build_main_dir() {
|
||||||
#
|
#
|
||||||
# usage: ynh_multimedia_addfolder --source_dir="source_dir" --dest_dir="dest_dir"
|
# usage: ynh_multimedia_addfolder --source_dir="source_dir" --dest_dir="dest_dir"
|
||||||
#
|
#
|
||||||
# | arg: -s, --source_dir= - Source directory - The real directory which contains your medias.
|
# | arg: --source_dir= - Source directory - The real directory which contains your medias.
|
||||||
# | arg: -d, --dest_dir= - Destination directory - The name and the place of the symbolic link, relative to "/home/yunohost.multimedia"
|
# | arg: --dest_dir= - Destination directory - The name and the place of the symbolic link, relative to "/home/yunohost.multimedia"
|
||||||
#
|
#
|
||||||
# This "directory" will be a symbolic link to a existing directory.
|
# This "directory" will be a symbolic link to a existing directory.
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.2 or higher.
|
|
||||||
ynh_multimedia_addfolder() {
|
ynh_multimedia_addfolder() {
|
||||||
|
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
|
@ -82,21 +78,12 @@ ynh_multimedia_addfolder() {
|
||||||
setfacl -RL -m m::rwx "$source_dir"
|
setfacl -RL -m m::rwx "$source_dir"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Allow an user to have an write authorisation in multimedia directories
|
# Add an user to the multimedia group, in turn having write permission in multimedia directories
|
||||||
#
|
#
|
||||||
# usage: ynh_multimedia_addaccess user_name
|
# usage: ynh_multimedia_addaccess user_name
|
||||||
#
|
#
|
||||||
# | arg: -u, --user_name= - The name of the user which gain this access.
|
# | arg: user_name - The name of the user which gain this access.
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.2 or higher.
|
|
||||||
ynh_multimedia_addaccess() {
|
ynh_multimedia_addaccess() {
|
||||||
|
groupadd -f $MEDIA_GROUP
|
||||||
# ============ Argument parsing =============
|
usermod -a -G $MEDIA_GROUP $1
|
||||||
local -A args_array=([u]=user_name=)
|
|
||||||
local user_name
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
# ===========================================
|
|
||||||
|
|
||||||
groupadd -f multimedia
|
|
||||||
usermod -a -G multimedia $user_name
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ ynh_mysql_db_shell() {
|
||||||
|
|
||||||
# Create a database and grant optionnaly privilegies to a user
|
# Create a database and grant optionnaly privilegies to a user
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal] ... handled by the core / "database resource"
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_create_db db [user [pwd]]
|
# usage: ynh_mysql_create_db db [user [pwd]]
|
||||||
# | arg: db - the database name to create
|
# | arg: db - the database name to create
|
||||||
|
@ -42,7 +42,7 @@ ynh_mysql_create_db() {
|
||||||
|
|
||||||
# Drop a database
|
# Drop a database
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal] ... handled by the core / "database resource"
|
||||||
#
|
#
|
||||||
# If you intend to drop the database *and* the associated user,
|
# If you intend to drop the database *and* the associated user,
|
||||||
# consider using ynh_mysql_remove_db instead.
|
# consider using ynh_mysql_remove_db instead.
|
||||||
|
@ -57,7 +57,7 @@ ynh_mysql_drop_db() {
|
||||||
# Dump a database
|
# Dump a database
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_dump_db database
|
# usage: ynh_mysql_dump_db database
|
||||||
# | arg: -d, --database= - the database name to dump (by default, $db_name)
|
# | arg: database - the database name to dump (by default, $db_name)
|
||||||
# | ret: The mysqldump output
|
# | ret: The mysqldump output
|
||||||
#
|
#
|
||||||
# example: ynh_mysql_dump_db "roundcube" > ./dump.sql
|
# example: ynh_mysql_dump_db "roundcube" > ./dump.sql
|
||||||
|
@ -69,7 +69,7 @@ ynh_mysql_dump_db() {
|
||||||
|
|
||||||
# Create a user
|
# Create a user
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal] ... handled by the core / "database resource"
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_create_user user pwd [host]
|
# usage: ynh_mysql_create_user user pwd [host]
|
||||||
# | arg: user - the user name to create
|
# | arg: user - the user name to create
|
||||||
|
@ -84,7 +84,7 @@ ynh_mysql_create_user() {
|
||||||
# [internal]
|
# [internal]
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_user_exists user
|
# usage: ynh_mysql_user_exists user
|
||||||
# | arg: user= - the user for which to check existence
|
# | arg: user - the user for which to check existence
|
||||||
# | ret: 0 if the user exists, 1 otherwise.
|
# | ret: 0 if the user exists, 1 otherwise.
|
||||||
ynh_mysql_user_exists() {
|
ynh_mysql_user_exists() {
|
||||||
local user=$1
|
local user=$1
|
||||||
|
@ -93,6 +93,8 @@ ynh_mysql_user_exists() {
|
||||||
|
|
||||||
# Check if a mysql database exists
|
# Check if a mysql database exists
|
||||||
#
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
# usage: ynh_mysql_database_exists database
|
# usage: ynh_mysql_database_exists database
|
||||||
# | arg: database - the database for which to check existence
|
# | arg: database - the database for which to check existence
|
||||||
# | exit: Return 1 if the database doesn't exist, 0 otherwise
|
# | exit: Return 1 if the database doesn't exist, 0 otherwise
|
||||||
|
@ -104,7 +106,7 @@ ynh_mysql_database_exists() {
|
||||||
|
|
||||||
# Drop a user
|
# Drop a user
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal] ... handled by the core / "database resource"
|
||||||
#
|
#
|
||||||
# usage: ynh_mysql_drop_user user
|
# usage: ynh_mysql_drop_user user
|
||||||
# | arg: user - the user name to drop
|
# | arg: user - the user name to drop
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#
|
#
|
||||||
# This allows to enable/disable specific behaviors dependenging on the install
|
# This allows to enable/disable specific behaviors dependenging on the install
|
||||||
# location
|
# location
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_config_add_nginx() {
|
ynh_config_add_nginx() {
|
||||||
|
|
||||||
local finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
|
local finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
|
@ -36,19 +34,14 @@ ynh_config_add_nginx() {
|
||||||
# Remove the dedicated nginx config
|
# Remove the dedicated nginx config
|
||||||
#
|
#
|
||||||
# usage: ynh_config_remove_nginx
|
# usage: ynh_config_remove_nginx
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
|
||||||
ynh_config_remove_nginx() {
|
ynh_config_remove_nginx() {
|
||||||
ynh_safe_rm "/etc/nginx/conf.d/$domain.d/$app.conf"
|
ynh_safe_rm "/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
ynh_systemctl --service=nginx --action=reload
|
ynh_systemctl --service=nginx --action=reload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Regen the nginx config in a change url context
|
# Regen the nginx config in a change url context
|
||||||
#
|
#
|
||||||
# usage: ynh_config_change_url_nginx
|
# usage: ynh_config_change_url_nginx
|
||||||
#
|
|
||||||
# Requires YunoHost version 11.1.9 or higher.
|
|
||||||
ynh_config_change_url_nginx() {
|
ynh_config_change_url_nginx() {
|
||||||
|
|
||||||
# Make a backup of the original NGINX config file if manually modified
|
# Make a backup of the original NGINX config file if manually modified
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
n_install_dir="/opt/node_n"
|
readonly N_INSTALL_DIR="/opt/node_n"
|
||||||
node_version_path="$n_install_dir/n/versions/node"
|
|
||||||
# N_PREFIX is the directory of n, it needs to be loaded as a environment variable.
|
# N_PREFIX is the directory of n, it needs to be loaded as a environment variable.
|
||||||
export N_PREFIX="$n_install_dir"
|
export N_PREFIX="$N_INSTALL_DIR"
|
||||||
|
|
||||||
|
# [internal]
|
||||||
_ynh_load_nodejs_in_path_and_other_tweaks() {
|
_ynh_load_nodejs_in_path_and_other_tweaks() {
|
||||||
|
|
||||||
# Get the absolute path of this version of node
|
# Get the absolute path of this version of node
|
||||||
local nodejs_path="$node_version_path/$nodejs_version/bin"
|
nodejs_dir="$N_INSTALL_DIR/n/versions/node/$nodejs_version/bin"
|
||||||
|
|
||||||
# Load the path of this version of node in $PATH
|
# Load the path of this version of node in $PATH
|
||||||
if [[ :$PATH: != *":$nodejs_path"* ]]; then
|
if [[ :$PATH: != *":$nodejs_dir"* ]]; then
|
||||||
PATH="$nodejs_path:$PATH"
|
PATH="$nodejs_dir:$PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Export PATH such that it's available through sudo -E / ynh_exec_as $app
|
# Export PATH such that it's available through sudo -E / ynh_exec_as $app
|
||||||
|
@ -28,29 +28,27 @@ _ynh_load_nodejs_in_path_and_other_tweaks() {
|
||||||
|
|
||||||
# Install a specific version of nodejs, using 'n'
|
# Install a specific version of nodejs, using 'n'
|
||||||
#
|
#
|
||||||
# The installed version is defined by $nodejs_version which should be defined as global prior to calling this helper
|
# The installed version is defined by `$nodejs_version` which should be defined as global prior to calling this helper
|
||||||
#
|
#
|
||||||
# usage: ynh_nodejs_install
|
# usage: ynh_nodejs_install
|
||||||
#
|
#
|
||||||
# `n` (Node version management) uses the `PATH` variable to store the path of the version of node it is going to use.
|
# `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
|
# That's how it changes the version
|
||||||
#
|
#
|
||||||
# Adds the appropriate, specific version of nodejs to the PATH variable (which
|
# The helper adds the appropriate, specific version of nodejs to the `$PATH` variable (which
|
||||||
# is also exported, to ease the use of ynh_exec_as_app). Also define variable
|
# is preserved when calling ynh_exec_as_app). Also defines:
|
||||||
# PATH_with_nodejs to be used in the systemd config
|
# - `$path_with_nodejs` to be used in the systemd config (`Environment="PATH=__PATH_WITH_NODEJS__"`)
|
||||||
# (Environment="PATH=__PATH_WITH_NODEJS__")
|
# - `$nodejs_dir`, the directory containing the specific version of nodejs, which may be used in the systemd config too (e.g. `ExecStart=__NODEJS_DIR__/node foo bar`)
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
|
||||||
ynh_nodejs_install() {
|
ynh_nodejs_install() {
|
||||||
# Use n, https://github.com/tj/n to manage the nodejs versions
|
# Use n, https://github.com/tj/n to manage the nodejs versions
|
||||||
|
|
||||||
[[ -n "${nodejs_version:-}" ]] || ynh_die "\$nodejs_version should be defined prior to calling ynh_nodejs_install"
|
[[ -n "${nodejs_version:-}" ]] || ynh_die "\$nodejs_version should be defined prior to calling ynh_nodejs_install"
|
||||||
|
|
||||||
# Create $n_install_dir
|
# Create $N_INSTALL_DIR
|
||||||
mkdir --parents "$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:@@')
|
||||||
|
|
||||||
|
@ -59,10 +57,10 @@ ynh_nodejs_install() {
|
||||||
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
|
||||||
|
|
||||||
# Install (or update if YunoHost vendor/ folder updated since last install) n
|
# Install (or update if YunoHost vendor/ folder updated since last install) n
|
||||||
mkdir -p $n_install_dir/bin/
|
mkdir -p $N_INSTALL_DIR/bin/
|
||||||
cp "$YNH_HELPERS_DIR/vendor/n/n" $n_install_dir/bin/n
|
cp "$YNH_HELPERS_DIR/vendor/n/n" $N_INSTALL_DIR/bin/n
|
||||||
# Tweak for n to understand it's installed in $N_PREFIX
|
# Tweak for n to understand it's installed in $N_PREFIX
|
||||||
ynh_replace --match="^N_PREFIX=\${N_PREFIX-.*}$" --replace="N_PREFIX=\${N_PREFIX-$N_PREFIX}" --file="$n_install_dir/bin/n"
|
ynh_replace --match="^N_PREFIX=\${N_PREFIX-.*}$" --replace="N_PREFIX=\${N_PREFIX-$N_PREFIX}" --file="$N_INSTALL_DIR/bin/n"
|
||||||
|
|
||||||
# Restore /usr/local/bin in PATH
|
# Restore /usr/local/bin in PATH
|
||||||
PATH=$CLEAR_PATH
|
PATH=$CLEAR_PATH
|
||||||
|
@ -80,16 +78,18 @@ ynh_nodejs_install() {
|
||||||
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 $N_INSTALL_DIR/n/versions/node/$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" ]; then
|
if [ ! -e "$N_INSTALL_DIR/n/versions/node/$nodejs_version" ]; then
|
||||||
ln --symbolic --force --no-target-directory $node_version_path/$real_nodejs_version $node_version_path/$nodejs_version
|
ln --symbolic --force --no-target-directory \
|
||||||
|
$N_INSTALL_DIR/n/versions/node/$real_nodejs_version \
|
||||||
|
$N_INSTALL_DIR/n/versions/node/$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 --key=nodejs_version --value=$nodejs_version
|
ynh_app_setting_set --key=nodejs_version --value=$nodejs_version
|
||||||
|
@ -104,24 +104,21 @@ ynh_nodejs_install() {
|
||||||
# This helper will check if another app uses the same version of node.
|
# This helper will check if another app uses the same version of node.
|
||||||
# - If not, this version of node will be removed.
|
# - If not, this version of node will be removed.
|
||||||
# - If no other app uses node, n will be also removed.
|
# - If no other app uses node, n will be also removed.
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
|
||||||
ynh_nodejs_remove() {
|
ynh_nodejs_remove() {
|
||||||
|
|
||||||
[[ -n "${nodejs_version:-}" ]] || ynh_die "\$nodejs_version should be defined prior to calling ynh_nodejs_remove"
|
[[ -n "${nodejs_version:-}" ]] || ynh_die "\$nodejs_version should be defined prior to calling ynh_nodejs_remove"
|
||||||
|
|
||||||
# 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"; then
|
if ! grep --quiet "$nodejs_version" "$N_INSTALL_DIR/ynh_app_version"; 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" ]; then
|
if [ ! -s "$N_INSTALL_DIR/ynh_app_version" ]; then
|
||||||
ynh_safe_rm "$n_install_dir"
|
ynh_safe_rm "$N_INSTALL_DIR"
|
||||||
ynh_safe_rm "/usr/local/n"
|
|
||||||
sed --in-place "/N_PREFIX/d" /root/.bashrc
|
sed --in-place "/N_PREFIX/d" /root/.bashrc
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,14 +27,14 @@
|
||||||
# usage: ynh_permission_create --permission="permission" [--url="url"] [--additional_urls="second-url" [ "third-url" ]] [--auth_header=true|false]
|
# usage: ynh_permission_create --permission="permission" [--url="url"] [--additional_urls="second-url" [ "third-url" ]] [--auth_header=true|false]
|
||||||
# [--allowed=group1 [ group2 ]] [--label="label"] [--show_tile=true|false]
|
# [--allowed=group1 [ group2 ]] [--label="label"] [--show_tile=true|false]
|
||||||
# [--protected=true|false]
|
# [--protected=true|false]
|
||||||
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist)
|
# | arg: --permission= - the name for the permission (by default a permission named "main" already exist)
|
||||||
# | arg: -u, --url= - (optional) URL for which access will be allowed/forbidden. Note that if 'show_tile' is enabled, this URL will be the URL of the tile.
|
# | arg: --url= - (optional) URL for which access will be allowed/forbidden. Note that if 'show_tile' is enabled, this URL will be the URL of the tile.
|
||||||
# | arg: -A, --additional_urls= - (optional) List of additional URL for which access will be allowed/forbidden
|
# | arg: --additional_urls= - (optional) List of additional URL for which access will be allowed/forbidden
|
||||||
# | arg: -h, --auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application. Default is true
|
# | arg: --auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application. Default is true
|
||||||
# | arg: -a, --allowed= - (optional) A list of group/user to allow for the permission
|
# | arg: --allowed= - (optional) A list of group/user to allow for the permission
|
||||||
# | arg: -l, --label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. Default is "APP_LABEL (permission name)".
|
# | arg: --label= - (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. Default is "APP_LABEL (permission name)".
|
||||||
# | arg: -t, --show_tile= - (optional) Define if a tile will be shown in the SSO. If yes the name of the tile will be the 'label' parameter. Defaults to false for the permission different than 'main'.
|
# | arg: --show_tile= - (optional) Define if a tile will be shown in the SSO. If yes the name of the tile will be the 'label' parameter. Defaults to false for the permission different than 'main'.
|
||||||
# | arg: -P, --protected= - (optional) Define if this permission is protected. If it is protected the administrator won't be able to add or remove the visitors group of this permission. Defaults to 'false'.
|
# | arg: --protected= - (optional) Define if this permission is protected. If it is protected the administrator won't be able to add or remove the visitors group of this permission. Defaults to 'false'.
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
# [packagingv1]
|
||||||
#
|
#
|
||||||
|
@ -62,9 +62,6 @@
|
||||||
#
|
#
|
||||||
# Generally this feature is usefull to authenticate automatically the user in the application but in some case the application don't work with theses header and theses header need to be disabled to have the application to work correctly.
|
# Generally this feature is usefull to authenticate automatically the user in the application but in some case the application don't work with theses header and theses header need to be disabled to have the application to work correctly.
|
||||||
# See https://github.com/YunoHost/issues/issues/1420 for more informations
|
# See https://github.com/YunoHost/issues/issues/1420 for more informations
|
||||||
#
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.7.0 or higher.
|
|
||||||
ynh_permission_create() {
|
ynh_permission_create() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([p]=permission= [u]=url= [A]=additional_urls= [h]=auth_header= [a]=allowed= [l]=label= [t]=show_tile= [P]=protected=)
|
local -A args_array=([p]=permission= [u]=url= [A]=additional_urls= [h]=auth_header= [a]=allowed= [l]=label= [t]=show_tile= [P]=protected=)
|
||||||
|
@ -145,14 +142,10 @@ ynh_permission_create() {
|
||||||
|
|
||||||
# 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)
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# example: ynh_permission_delete --permission=editors
|
# example: ynh_permission_delete --permission=editors
|
||||||
#
|
#
|
||||||
# usage: ynh_permission_delete --permission="permission"
|
# usage: ynh_permission_delete --permission="permission"
|
||||||
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed)
|
# | arg: --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed)
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.7.0 or higher.
|
|
||||||
ynh_permission_delete() {
|
ynh_permission_delete() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([p]=permission=)
|
local -A args_array=([p]=permission=)
|
||||||
|
@ -165,13 +158,9 @@ ynh_permission_delete() {
|
||||||
|
|
||||||
# Check if a permission exists
|
# Check if a permission exists
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_permission_exists --permission=permission
|
# usage: ynh_permission_exists --permission=permission
|
||||||
# | arg: -p, --permission= - the permission to check
|
# | arg: --permission= - the permission to check
|
||||||
# | exit: Return 1 if the permission doesn't exist, 0 otherwise
|
# | exit: Return 1 if the permission doesn't exist, 0 otherwise
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.7.0 or higher.
|
|
||||||
ynh_permission_exists() {
|
ynh_permission_exists() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([p]=permission=)
|
local -A args_array=([p]=permission=)
|
||||||
|
@ -185,18 +174,14 @@ ynh_permission_exists() {
|
||||||
|
|
||||||
# Redefine the url associated to a permission
|
# Redefine the url associated to a permission
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_permission_url --permission "permission" [--url="url"] [--add_url="new-url" [ "other-new-url" ]] [--remove_url="old-url" [ "other-old-url" ]]
|
# usage: ynh_permission_url --permission "permission" [--url="url"] [--add_url="new-url" [ "other-new-url" ]] [--remove_url="old-url" [ "other-old-url" ]]
|
||||||
# [--auth_header=true|false] [--clear_urls]
|
# [--auth_header=true|false] [--clear_urls]
|
||||||
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" is removed automatically when the app is removed)
|
# | arg: --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. Note that if you want to remove url you can pass an empty sting as arguments ("").
|
# | arg: --url= - (optional) URL for which access will be allowed/forbidden. Note that if you want to remove url you can pass an empty sting as arguments ("").
|
||||||
# | arg: -a, --add_url= - (optional) List of additional url to add for which access will be allowed/forbidden.
|
# | arg: --add_url= - (optional) List of additional url to add for which access will be allowed/forbidden.
|
||||||
# | arg: -r, --remove_url= - (optional) List of additional url to remove for which access will be allowed/forbidden
|
# | arg: --remove_url= - (optional) List of additional url to remove for which access will be allowed/forbidden
|
||||||
# | arg: -h, --auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application
|
# | arg: --auth_header= - (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application
|
||||||
# | arg: -c, --clear_urls - (optional) Clean all urls (url and additional_urls)
|
# | arg: --clear_urls - (optional) Clean all urls (url and additional_urls)
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.7.0 or higher.
|
|
||||||
ynh_permission_url() {
|
ynh_permission_url() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([p]=permission= [u]=url= [a]=add_url= [r]=remove_url= [h]=auth_header= [c]=clear_urls)
|
local -A args_array=([p]=permission= [u]=url= [a]=add_url= [r]=remove_url= [h]=auth_header= [c]=clear_urls)
|
||||||
|
@ -255,15 +240,11 @@ ynh_permission_url() {
|
||||||
|
|
||||||
# Update a permission for the app
|
# Update a permission for the app
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]]
|
# usage: ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]]
|
||||||
#
|
#
|
||||||
# | arg: -p, --permission= - the name for the permission (by default a permission named "main" already exist)
|
# | arg: --permission= - the name for the permission (by default a permission named "main" already exist)
|
||||||
# | arg: -a, --add= - the list of group or users to enable add to the permission
|
# | arg: --add= - the list of group or users to enable add to the permission
|
||||||
# | arg: -r, --remove= - the list of group or users to remove from the permission
|
# | arg: --remove= - the list of group or users to remove from the permission
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.7.0 or higher.
|
|
||||||
ynh_permission_update() {
|
ynh_permission_update() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([p]=permission= [a]=add= [r]=remove=)
|
local -A args_array=([p]=permission= [a]=add= [r]=remove=)
|
||||||
|
@ -302,11 +283,9 @@ ynh_permission_update() {
|
||||||
# example: ynh_permission_has_user --permission=main --user=visitors
|
# example: ynh_permission_has_user --permission=main --user=visitors
|
||||||
#
|
#
|
||||||
# usage: ynh_permission_has_user --permission=permission --user=user
|
# usage: ynh_permission_has_user --permission=permission --user=user
|
||||||
# | arg: -p, --permission= - the permission to check
|
# | arg: --permission= - the permission to check
|
||||||
# | arg: -u, --user= - the user seek in the permission
|
# | arg: --user= - the user seek in the permission
|
||||||
# | exit: Return 1 if the permission doesn't have that user or doesn't exist, 0 otherwise
|
# | 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() {
|
ynh_permission_has_user() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([p]=permission= [u]=user=)
|
local -A args_array=([p]=permission= [u]=user=)
|
||||||
|
|
|
@ -3,105 +3,72 @@
|
||||||
# (this is used in the apt helpers, big meh ...)
|
# (this is used in the apt helpers, big meh ...)
|
||||||
readonly YNH_DEFAULT_PHP_VERSION=7.4
|
readonly YNH_DEFAULT_PHP_VERSION=7.4
|
||||||
|
|
||||||
# Legacy: auto-convert phpversion to php_version (for consistency with nodejs_version, ruby_version, ...)
|
|
||||||
if [[ -n "${app:-}" ]] && [[ -n "${phpversion:-}" ]]
|
|
||||||
then
|
|
||||||
if [[ -z "${php_version:-}" ]]
|
|
||||||
then
|
|
||||||
php_version=$phpversion
|
|
||||||
ynh_app_setting_set --key=php_version --value=$php_version
|
|
||||||
fi
|
|
||||||
ynh_app_setting_delete --key=phpversion
|
|
||||||
unset phpversion
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create a dedicated PHP-FPM config
|
# Create a dedicated PHP-FPM config
|
||||||
#
|
#
|
||||||
# usage: ynh_config_add_phpfpm
|
# usage: ynh_config_add_phpfpm
|
||||||
#
|
#
|
||||||
# This helper assumes the app has an conf/extra_php-fpm.conf snippet
|
# This will automatically generate an appropriate PHP-FPM configuration for this app.
|
||||||
#
|
#
|
||||||
# The actual PHP configuration will be automatically generated,
|
# The resulting configuration will be deployed to the appropriate place:
|
||||||
# and your extra_php-fpm.conf will be appended (typically contains PHP upload limits)
|
# `/etc/php/$php_version/fpm/pool.d/$app.conf`
|
||||||
#
|
#
|
||||||
# The resulting configuration will be deployed to the appropriate place, /etc/php/$php_version/fpm/pool.d/$app.conf
|
# If the app provides a `conf/extra_php-fpm.conf` template, it will be appended
|
||||||
|
# to the generated configuration. (In the vast majority of cases, this shouldnt
|
||||||
|
# be necessary)
|
||||||
#
|
#
|
||||||
# Performance-related options in the PHP conf, such as :
|
# $php_version should be defined prior to calling this helper, but there should
|
||||||
# pm.max_children, pm.start_servers, pm.min_spare_servers pm.max_spare_servers
|
# be no reason to manually set it, as it is automatically set by the apt
|
||||||
# are computed from two parameters called "usage" and "footprint" which can be set to low/medium/high. (cf details below)
|
# helpers/resources when installing phpX.Y dependencies (PHP apps should at
|
||||||
|
# least install phpX.Y-fpm using the `apt` helper/resource)
|
||||||
#
|
#
|
||||||
# If you wish to tweak those, please initialize the settings `fpm_usage` and `fpm_footprint`
|
# `$php_group` can be defined as a global (from `_common.sh`) if the worker
|
||||||
# *prior* to calling this helper. Otherwise, "low" will be used as a default for both values.
|
# processes should run with a different group than `$app`
|
||||||
#
|
#
|
||||||
# Otherwise, if you want the user to have control over these, we encourage to create a config panel
|
# Additional "pm" and "php_admin_value" settings which are meant to be possibly
|
||||||
# (which should ultimately be standardized by the core ...)
|
# configurable by admins from a future standard config panel at some point,
|
||||||
|
# related to performance and availability of the app, for which tweaking may be
|
||||||
|
# required if the app is used by "plenty" of users and other memory/CPU load
|
||||||
|
# considerations....
|
||||||
#
|
#
|
||||||
# The footprint of the service will be used to defined the maximum footprint we can allow, which is half the maximum RAM.
|
# If you have good reasons to be willing to use different
|
||||||
# So it will be used to defined 'pm.max_children'
|
# defaults than the one set by this helper (while still allowing admin to
|
||||||
# A lower value for the footprint will allow more children for 'pm.max_children'. And so for
|
# override it) you should use `ynh_app_setting_set_default`
|
||||||
# '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.
|
# - `$php_upload_max_filezise`: corresponds upload_max_filesize and post_max_size. Defaults to 50M
|
||||||
# A value set as 'low' will set the process manager to 'ondemand'. Children will start only if the
|
# - `$php_process_management`: corresponds to "pm" (ondemand, dynamic, static). Defaults to ondemand
|
||||||
# service is used, otherwise no child will stay alive. This config gives the lower footprint when the
|
# - `$php_max_children`: by default, computed from "total RAM" divided by 40, cf `_default_php_max_children`
|
||||||
# service is idle. But will use more proc since it has to start a child as soon it's used.
|
# - `$php_memory_limit`: by default, 128M (from global php.ini)
|
||||||
# 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.
|
# Note that if $php_process_management is set to "dynamic", then these
|
||||||
# The number of children can grow if needed. The footprint can stay low if the service is idle, but
|
# variables MUST be defined prior to calling the helper (no default value) ...
|
||||||
# not null. The impact on the proc is a little bit less than 'ondemand' as there's always a few
|
# Check PHP-FPM's manual for more info on what these are (: ...
|
||||||
# children already available.
|
#
|
||||||
# Set as 'high', the process manager will be set at 'static'. There will be always as many children as
|
# - `$php_start_servers`
|
||||||
# 'pm.max_children', the footprint is important (but will be set as maximum a quarter of the maximum
|
# - `$php_min_spare_servers`
|
||||||
# RAM) but the impact on the proc is lower. The service will be quick to answer as there's always many
|
# - `$php_max_spare_servers`
|
||||||
# children ready to answer.
|
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_config_add_phpfpm() {
|
ynh_config_add_phpfpm() {
|
||||||
# ============ Argument parsing =============
|
|
||||||
local -A args_array=([g]=group=)
|
|
||||||
local group
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
group=${group:-}
|
|
||||||
# ===========================================
|
|
||||||
|
|
||||||
# If the PHP version changed, remove the old fpm conf
|
[[ -n "${php_version:-}" ]] || ynh_die "\$php_version should be defined prior to calling ynh_config_add_phpfpm. You should not need to define it manually, it is automatically set by the apt helper when installing the phpX.Y- depenencies"
|
||||||
# (NB: This stuff is also handled by the apt helper, which is usually triggered before this helper)
|
|
||||||
# FIXME: so is this still needed @_@
|
|
||||||
local old_php_version=$(ynh_app_setting_get --key=php_version)
|
|
||||||
if [ -n "$old_php_version" ] && [ "$old_php_version" != "$php_version" ]; then
|
|
||||||
local old_php_fpm_config_dir=$(ynh_app_setting_get --key=fpm_config_dir)
|
|
||||||
local old_php_finalphpconf="$old_php_fpm_config_dir/pool.d/$app.conf"
|
|
||||||
|
|
||||||
if [[ -f "$old_php_finalphpconf" ]]
|
# Apps may define $php_group as a global (e.g. from _common.sh) to change this
|
||||||
then
|
# (this is not meant to be overridable by users)
|
||||||
ynh_backup_if_checksum_is_different "$old_php_finalphpconf"
|
local php_group=${php_group:-$app}
|
||||||
ynh_remove_fpm_config
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
local fpm_service="php${php_version}-fpm"
|
# Meant to be overridable by users from a standard config panel at some point ...
|
||||||
local fpm_config_dir="/etc/php/$php_version/fpm"
|
# Apps willing to tweak these should use ynh_setting_set_default_value (in install and upgrade?)
|
||||||
|
#
|
||||||
|
local php_upload_max_filesize=${php_upload_max_filesize:-50M}
|
||||||
|
local php_process_management=${php_process_management:-ondemand} # alternatively 'dynamic' or 'static'
|
||||||
|
local php_max_children=${php_max_children:-$(_default_php_max_children)}
|
||||||
|
local php_memory_limit=${php_memory_limit:-128M} # default value is from global php.ini
|
||||||
|
|
||||||
# Create the directory for FPM pools
|
local phpfpm_template=$(mktemp)
|
||||||
mkdir --parents "$fpm_config_dir/pool.d"
|
cat << EOF > $phpfpm_template
|
||||||
|
|
||||||
# FIXME: zzzz do we really need those ...
|
|
||||||
ynh_app_setting_set --key=fpm_config_dir --value="$fpm_config_dir"
|
|
||||||
ynh_app_setting_set --key=fpm_service --value="$fpm_service"
|
|
||||||
ynh_app_setting_set --key=php_version --value=$php_version
|
|
||||||
|
|
||||||
# Define the values to use for the configuration of PHP.
|
|
||||||
_ynh_get_scalable_phpfpm
|
|
||||||
|
|
||||||
local phpfpm_group=$([[ -n "$group" ]] && echo "$group" || echo "$app")
|
|
||||||
local phpfpm_path="$YNH_APP_BASEDIR/conf/php-fpm.conf"
|
|
||||||
echo "
|
|
||||||
[__APP__]
|
[__APP__]
|
||||||
|
|
||||||
user = __APP__
|
user = __APP__
|
||||||
group = __PHPFPM_GROUP__
|
group = __PHP_GROUP__
|
||||||
|
|
||||||
chdir = __INSTALL_DIR__
|
chdir = __INSTALL_DIR__
|
||||||
|
|
||||||
|
@ -109,209 +76,74 @@ listen = /var/run/php/php__PHP_VERSION__-fpm-__APP__.sock
|
||||||
listen.owner = www-data
|
listen.owner = www-data
|
||||||
listen.group = www-data
|
listen.group = www-data
|
||||||
|
|
||||||
pm = __PHP_PM__
|
pm = __PHP_PROCESS_MANAGEMENT__
|
||||||
pm.max_children = __PHP_MAX_CHILDREN__
|
pm.max_children = __PHP_MAX_CHILDREN__
|
||||||
pm.max_requests = 500
|
pm.max_requests = 500
|
||||||
request_terminate_timeout = 1d
|
request_terminate_timeout = 1d
|
||||||
" >"$phpfpm_path"
|
|
||||||
|
|
||||||
if [ "$php_pm" = "dynamic" ]; then
|
EOF
|
||||||
echo "
|
if [ "$php_process_management" = "dynamic" ]; then
|
||||||
|
cat << EOF >> $phpfpm_template
|
||||||
pm.start_servers = __PHP_START_SERVERS__
|
pm.start_servers = __PHP_START_SERVERS__
|
||||||
pm.min_spare_servers = __PHP_MIN_SPARE_SERVERS__
|
pm.min_spare_servers = __PHP_MIN_SPARE_SERVERS__
|
||||||
pm.max_spare_servers = __PHP_MAX_SPARE_SERVERS__
|
pm.max_spare_servers = __PHP_MAX_SPARE_SERVERS__
|
||||||
" >>"$phpfpm_path"
|
EOF
|
||||||
|
elif [ "$php_process_management" = "ondemand" ]; then
|
||||||
elif [ "$php_pm" = "ondemand" ]; then
|
cat << EOF >> $phpfpm_template
|
||||||
echo "
|
|
||||||
pm.process_idle_timeout = 10s
|
pm.process_idle_timeout = 10s
|
||||||
" >>"$phpfpm_path"
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Concatene the extra config.
|
cat << EOF >> $phpfpm_template
|
||||||
|
php_admin_value[upload_max_filesize] = __PHP_UPLOAD_MAX_FILESIZE__
|
||||||
|
php_admin_value[post_max_size] = __PHP_UPLOAD_MAX_FILESIZE__
|
||||||
|
php_admin_value[memory_limit] = __PHP_MEMORY_LIMIT__
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Concatene the extra config
|
||||||
if [ -e $YNH_APP_BASEDIR/conf/extra_php-fpm.conf ]; then
|
if [ -e $YNH_APP_BASEDIR/conf/extra_php-fpm.conf ]; then
|
||||||
cat $YNH_APP_BASEDIR/conf/extra_php-fpm.conf >>"$phpfpm_path"
|
cat $YNH_APP_BASEDIR/conf/extra_php-fpm.conf >> "$phpfpm_template"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ynh_config_add --template="$phpfpm_path" --destination="$fpm_config_dir/pool.d/$app.conf"
|
# Make sure the fpm pool dir exists
|
||||||
|
mkdir --parents "/etc/php/$php_version/fpm/pool.d"
|
||||||
|
# And hydrate configuration
|
||||||
|
ynh_config_add --template="$phpfpm_template" --destination="/etc/php/$php_version/fpm/pool.d/$app.conf"
|
||||||
|
|
||||||
# Validate that the new php conf doesn't break php-fpm entirely
|
# Validate that the new php conf doesn't break php-fpm entirely
|
||||||
if ! php-fpm${php_version} --test 2> /dev/null; then
|
if ! php-fpm${php_version} --test 2> /dev/null; then
|
||||||
php-fpm${php_version} --test || true
|
php-fpm${php_version} --test || true
|
||||||
ynh_safe_rm "$fpm_config_dir/pool.d/$app.conf"
|
ynh_safe_rm "/etc/php/$php_version/fpm/pool.d/$app.conf"
|
||||||
ynh_die "The new configuration broke php-fpm?"
|
ynh_die "The new configuration broke php-fpm?"
|
||||||
fi
|
fi
|
||||||
ynh_systemctl --service=$fpm_service --action=reload
|
|
||||||
|
ynh_systemctl --service=php${php_version}-fpm --action=reload
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove the dedicated PHP-FPM config
|
# Remove the dedicated PHP-FPM config
|
||||||
#
|
#
|
||||||
# usage: ynh_config_remove_phpfpm
|
# usage: ynh_config_remove_phpfpm
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
|
||||||
ynh_config_remove_phpfpm() {
|
ynh_config_remove_phpfpm() {
|
||||||
local fpm_config_dir=$(ynh_app_setting_get --key=fpm_config_dir)
|
ynh_safe_rm "/etc/php/$php_version/fpm/pool.d/$app.conf"
|
||||||
|
|
||||||
ynh_safe_rm "$fpm_config_dir/pool.d/$app.conf"
|
|
||||||
ynh_systemctl --service="php${php_version}-fpm" --action=reload
|
ynh_systemctl --service="php${php_version}-fpm" --action=reload
|
||||||
}
|
}
|
||||||
|
|
||||||
# Define the values to configure PHP-FPM
|
_default_php_max_children() {
|
||||||
#
|
# Get the total of RAM available
|
||||||
# [internal]
|
local total_ram=$(ynh_get_ram --total)
|
||||||
#
|
|
||||||
# usage: _ynh_get_scalable_phpfpm
|
|
||||||
# Footprint can be defined via the "fpm_footprint", to be set prior to calling this helper
|
|
||||||
# low - Less than 20 MB of RAM by pool.
|
|
||||||
# medium - Between 20 MB and 40 MB of RAM by pool.
|
|
||||||
# high - More than 40 MB of RAM by pool.
|
|
||||||
# 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
|
|
||||||
#
|
|
||||||
# Usage can be defined via the "fpm_usage", to be set prior to calling this helper
|
|
||||||
# low - Personal usage, behind the SSO.
|
|
||||||
# medium - Low usage, few people or/and publicly accessible.
|
|
||||||
# high - High usage, frequently visited website.
|
|
||||||
#
|
|
||||||
_ynh_get_scalable_phpfpm() {
|
|
||||||
|
|
||||||
# If no usage provided, default to the value existing in setting ... or to low
|
|
||||||
local fpm_usage_in_setting=$(ynh_app_setting_get --key=fpm_usage)
|
|
||||||
local usage=${fpm_usage_in_setting:-low}
|
|
||||||
ynh_app_setting_set --key=fpm_usage --value=$usage
|
|
||||||
|
|
||||||
# If no footprint provided, default to the value existing in setting ... or to low
|
|
||||||
local fpm_footprint_in_setting=$(ynh_app_setting_get --key=fpm_footprint)
|
|
||||||
local footprint=${fpm_footprint_in_setting:-low}
|
|
||||||
ynh_app_setting_set --key=fpm_footprint --value=$footprint
|
|
||||||
|
|
||||||
# Set all characters as lowercase
|
|
||||||
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 "Does not recognize '$usage' as an usage value."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the total of RAM available, except swap.
|
|
||||||
local max_ram=$(ynh_get_ram --total)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
# The value of pm.max_children is the total amount of ram divide by 2,
|
||||||
|
# divide again by 20MB (= a default, classic worker footprint) This is
|
||||||
|
# designed such that if PHP-FPM start the maximum of children, it won't
|
||||||
|
# exceed half of the ram.
|
||||||
|
local php_max_children="$(($total_ram / 40))"
|
||||||
|
# Make sure we get at least max_children = 1
|
||||||
|
if [ $php_max_children -le 0 ]; then
|
||||||
|
php_max_children=1
|
||||||
# To not overload the proc, limit the number of children to 4 times the number of cores.
|
# To not overload the proc, limit the number of children to 4 times the number of cores.
|
||||||
local core_number=$(nproc)
|
elif [ $php_max_children -gt "$(($(nproc) * 4))" ]; then
|
||||||
local max_proc=$(($core_number * 4))
|
php_max_children="$(($(nproc) * 4))"
|
||||||
if [ $php_max_children -gt $max_proc ]; then
|
|
||||||
php_max_children=$max_proc
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get a potential forced value for php_max_children
|
echo "$php_max_children"
|
||||||
local php_forced_max_children=$(ynh_app_setting_get --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
|
|
||||||
}
|
|
||||||
|
|
||||||
# Execute a command with Composer
|
|
||||||
#
|
|
||||||
# Will use $install_dir as workdir unless $composer_workdir exists (but that shouldnt be necessary)
|
|
||||||
#
|
|
||||||
# You may also define composer_user=root prior to call this helper if you absolutely need composer to run as root, but this is discouraged...
|
|
||||||
#
|
|
||||||
# usage: ynh_composer_exec commands
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.2 or higher.
|
|
||||||
ynh_composer_exec() {
|
|
||||||
local workdir="${composer_workdir:-$install_dir}"
|
|
||||||
|
|
||||||
COMPOSER_HOME="$workdir/.composer" \
|
|
||||||
COMPOSER_MEMORY_LIMIT=-1 \
|
|
||||||
sudo -E -u "${composer_user:-$app}" \
|
|
||||||
php${php_version} "$workdir/composer.phar" $@ \
|
|
||||||
-d "$workdir" --no-interaction --no-ansi 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Install and initialize Composer in the given directory
|
|
||||||
#
|
|
||||||
# The installed version is defined by $composer_version which should be defined
|
|
||||||
# as global prior to calling this helper.
|
|
||||||
#
|
|
||||||
# Will use $install_dir as workdir unless $composer_workdir exists (but that shouldnt be necessary)
|
|
||||||
#
|
|
||||||
# usage: ynh_composer_install
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.2 or higher.
|
|
||||||
ynh_composer_install() {
|
|
||||||
local workdir="${composer_workdir:-$install_dir}"
|
|
||||||
|
|
||||||
[[ -n "${composer_version}" ]] || ynh_die "\$composer_version should be defined before calling ynh_composer_install. (In the past, this was called \$YNH_COMPOSER_VERSION)"
|
|
||||||
|
|
||||||
[[ ! -e "$workdir/composer.phar" ]] || ynh_safe_rm $workdir/composer.phar
|
|
||||||
|
|
||||||
local composer_url="https://getcomposer.org/download/$composer_version/composer.phar"
|
|
||||||
|
|
||||||
# NB. we have to declare the var as local first,
|
|
||||||
# otherwise 'local foo=$(false) || echo 'pwet'" does'nt work
|
|
||||||
# because local always return 0 ...
|
|
||||||
local out
|
|
||||||
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
|
||||||
out=$(wget --tries 3 --no-dns-cache --timeout 900 --no-verbose --output-document=$workdir/composer.phar $composer_url 2>&1) \
|
|
||||||
|| ynh_die "$out"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ ynh_psql_db_shell() {
|
||||||
|
|
||||||
# Create a database and grant optionnaly privilegies to a user
|
# Create a database and grant optionnaly privilegies to a user
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal] ... handled by the core / "database resource"
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_create_db db [user]
|
# usage: ynh_psql_create_db db [user]
|
||||||
# | arg: db - the database name to create
|
# | arg: db - the database name to create
|
||||||
|
@ -42,7 +42,7 @@ ynh_psql_create_db() {
|
||||||
|
|
||||||
# Drop a database
|
# Drop a database
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal] ... handled by the core / "database resource"
|
||||||
#
|
#
|
||||||
# If you intend to drop the database *and* the associated user,
|
# If you intend to drop the database *and* the associated user,
|
||||||
# consider using ynh_psql_remove_db instead.
|
# consider using ynh_psql_remove_db instead.
|
||||||
|
@ -74,19 +74,21 @@ ynh_psql_dump_db() {
|
||||||
|
|
||||||
# Create a user
|
# Create a user
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal] ... handled by the core / "database resource"
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_create_user user pwd
|
# usage: ynh_psql_create_user user pwd
|
||||||
# | arg: user - the user name to create
|
# | arg: user - the user name to create
|
||||||
# | arg: pwd - the password to identify user by
|
# | arg: pwd - the password to identify user by
|
||||||
#
|
#
|
||||||
ynh_psql_create_user() {
|
ynh_psql_create_user() {
|
||||||
|
local user=$1
|
||||||
|
local pwd=$2
|
||||||
sudo --login --user=postgres psql <<< "CREATE USER $user WITH ENCRYPTED PASSWORD '$pwd'"
|
sudo --login --user=postgres psql <<< "CREATE USER $user WITH ENCRYPTED PASSWORD '$pwd'"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if a psql user exists
|
# Check if a psql user exists
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
# [internal]
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_user_exists user
|
# usage: ynh_psql_user_exists user
|
||||||
# | arg: user= - the user for which to check existence
|
# | arg: user= - the user for which to check existence
|
||||||
|
@ -99,6 +101,8 @@ ynh_psql_user_exists() {
|
||||||
|
|
||||||
# Check if a psql database exists
|
# Check if a psql database exists
|
||||||
#
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
# usage: ynh_psql_database_exists database
|
# usage: ynh_psql_database_exists database
|
||||||
# | arg: database - the database for which to check existence
|
# | arg: database - the database for which to check existence
|
||||||
# | exit: Return 1 if the database doesn't exist, 0 otherwise
|
# | exit: Return 1 if the database doesn't exist, 0 otherwise
|
||||||
|
@ -110,7 +114,7 @@ ynh_psql_database_exists() {
|
||||||
|
|
||||||
# Drop a user
|
# Drop a user
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal] ... handled by the core / "database resource"
|
||||||
#
|
#
|
||||||
# usage: ynh_psql_drop_user user
|
# usage: ynh_psql_drop_user user
|
||||||
# | arg: user - the user name to drop
|
# | arg: user - the user name to drop
|
||||||
|
|
|
@ -13,10 +13,8 @@ ynh_redis_get_free_db() {
|
||||||
|
|
||||||
db=0
|
db=0
|
||||||
# default Debian setting is 15 databases
|
# default Debian setting is 15 databases
|
||||||
for i in $(seq 0 "$max")
|
for i in $(seq 0 "$max"); do
|
||||||
do
|
if ! echo "$result" | grep -q "db$i"; then
|
||||||
if ! echo "$result" | grep -q "db$i"
|
|
||||||
then
|
|
||||||
db=$i
|
db=$i
|
||||||
break 1
|
break 1
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
rbenv_install_dir="/opt/rbenv"
|
readonly RBENV_INSTALL_DIR="/opt/rbenv"
|
||||||
ruby_version_path="$rbenv_install_dir/versions"
|
|
||||||
|
|
||||||
# RBENV_ROOT is the directory of rbenv, it needs to be loaded as a environment variable.
|
# RBENV_ROOT is the directory of rbenv, it needs to be loaded as a environment variable.
|
||||||
export RBENV_ROOT="$rbenv_install_dir"
|
export RBENV_ROOT="$RBENV_INSTALL_DIR"
|
||||||
export rbenv_root="$rbenv_install_dir"
|
export rbenv_root="$RBENV_INSTALL_DIR"
|
||||||
|
|
||||||
_ynh_load_ruby_in_path_and_other_tweaks() {
|
_ynh_load_ruby_in_path_and_other_tweaks() {
|
||||||
|
|
||||||
# Get the absolute path of this version of Ruby
|
# Get the absolute path of this version of Ruby
|
||||||
local ruby_path="$ruby_version_path/$app/bin"
|
ruby_dir="$RBENV_INSTALL_DIR/versions/$app/bin"
|
||||||
|
|
||||||
# Load the path of this version of ruby in $PATH
|
# Load the path of this version of ruby in $PATH
|
||||||
if [[ :$PATH: != *":$ruby_path"* ]]; then
|
if [[ :$PATH: != *":$ruby_dir"* ]]; then
|
||||||
PATH="$ruby_path:$PATH"
|
PATH="$ruby_dir:$PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Export PATH such that it's available through sudo -E / ynh_exec_as $app
|
# Export PATH such that it's available through sudo -E / ynh_exec_as $app
|
||||||
|
@ -26,36 +25,28 @@ _ynh_load_ruby_in_path_and_other_tweaks() {
|
||||||
|
|
||||||
# Sets the local application-specific Ruby version
|
# Sets the local application-specific Ruby version
|
||||||
pushd ${install_dir}
|
pushd ${install_dir}
|
||||||
$rbenv_install_dir/bin/rbenv local $ruby_version
|
$RBENV_INSTALL_DIR/bin/rbenv local $ruby_version
|
||||||
popd
|
popd
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install a specific version of Ruby using rbenv
|
# Install a specific version of Ruby using rbenv
|
||||||
#
|
#
|
||||||
# The installed version is defined by $ruby_version which should be defined as global prior to calling this helper
|
# The installed version is defined by `$ruby_version` which should be defined as global prior to calling this helper
|
||||||
#
|
|
||||||
# This helper creates a /etc/profile.d/rbenv.sh that configures PATH environment for rbenv
|
|
||||||
# for every LOGIN user, hence your user must have a defined shell (as opposed to /usr/sbin/nologin)
|
|
||||||
#
|
|
||||||
# Don't forget to execute ruby-dependent command in a login environment
|
|
||||||
# (e.g. sudo --login option)
|
|
||||||
# When not possible (e.g. in systemd service definition), please use direct path
|
|
||||||
# to rbenv shims (e.g. $RBENV_ROOT/shims/bundle)
|
|
||||||
#
|
#
|
||||||
# usage: ynh_ruby_install
|
# usage: ynh_ruby_install
|
||||||
#
|
#
|
||||||
# Adds the appropriate, specific version of ruby to the PATH variable (which
|
# The helper adds the appropriate, specific version of ruby to the `$PATH` variable (which
|
||||||
# is also exported, to ease the use of ynh_exec_as_app). Also define variable
|
# is preserved when calling ynh_exec_as_app). Also defines:
|
||||||
# PATH_with_ruby to be used in the systemd config
|
# - `$path_with_ruby` to be used in the systemd config (`Environment="PATH=__PATH_WITH_RUBY__"`)
|
||||||
# (Environment="PATH=__PATH_WITH_RUBY__")
|
# - `$ruby_dir`, the directory containing the specific version of ruby, which may be used in the systemd config too (e.g. `ExecStart=__RUBY_DIR__/ruby foo bar`)
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.2.2 or higher.
|
# This helper also creates a /etc/profile.d/rbenv.sh that configures PATH environment for rbenv
|
||||||
ynh_ruby_install() {
|
ynh_ruby_install() {
|
||||||
|
|
||||||
[[ -n "${ruby_version:-}" ]] || ynh_die "\$ruby_version should be defined prior to calling ynh_ruby_install"
|
[[ -n "${ruby_version:-}" ]] || ynh_die "\$ruby_version should be defined prior to calling ynh_ruby_install"
|
||||||
|
|
||||||
# Load rbenv path in PATH
|
# Load rbenv path in PATH
|
||||||
local CLEAR_PATH="$rbenv_install_dir/bin:$PATH"
|
local CLEAR_PATH="$RBENV_INSTALL_DIR/bin:$PATH"
|
||||||
|
|
||||||
# Remove /usr/local/bin in PATH in case of Ruby prior installation
|
# Remove /usr/local/bin in PATH in case of Ruby prior installation
|
||||||
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
||||||
|
@ -64,41 +55,41 @@ ynh_ruby_install () {
|
||||||
test -x /usr/bin/ruby && mv /usr/bin/ruby /usr/bin/ruby_rbenv
|
test -x /usr/bin/ruby && mv /usr/bin/ruby /usr/bin/ruby_rbenv
|
||||||
|
|
||||||
# Install or update rbenv
|
# Install or update rbenv
|
||||||
mkdir -p $rbenv_install_dir
|
mkdir -p $RBENV_INSTALL_DIR
|
||||||
rbenv="$(command -v rbenv $rbenv_install_dir/bin/rbenv | grep "$rbenv_install_dir/bin/rbenv" | head -1)"
|
rbenv="$(command -v rbenv $RBENV_INSTALL_DIR/bin/rbenv | grep "$RBENV_INSTALL_DIR/bin/rbenv" | head -1)"
|
||||||
if [ -n "$rbenv" ]; then
|
if [ -n "$rbenv" ]; then
|
||||||
pushd "${rbenv%/*/*}"
|
pushd "${rbenv%/*/*}"
|
||||||
if git remote -v 2> /dev/null | grep "https://github.com/rbenv/rbenv.git"; then
|
if git remote -v 2> /dev/null | grep "https://github.com/rbenv/rbenv.git"; then
|
||||||
echo "Updating rbenv..."
|
echo "Updating rbenv..."
|
||||||
git pull -q --tags origin master
|
git pull -q --tags origin master
|
||||||
ynh_ruby_try_bash_extension
|
_ynh_ruby_try_bash_extension
|
||||||
else
|
else
|
||||||
echo "Reinstalling rbenv..."
|
echo "Reinstalling rbenv..."
|
||||||
cd ..
|
cd ..
|
||||||
ynh_safe_rm $rbenv_install_dir
|
ynh_safe_rm $RBENV_INSTALL_DIR
|
||||||
mkdir -p $rbenv_install_dir
|
mkdir -p $RBENV_INSTALL_DIR
|
||||||
cd $rbenv_install_dir
|
cd $RBENV_INSTALL_DIR
|
||||||
git init -q
|
git init -q
|
||||||
git remote add -f -t master origin https://github.com/rbenv/rbenv.git > /dev/null 2>&1
|
git remote add -f -t master origin https://github.com/rbenv/rbenv.git > /dev/null 2>&1
|
||||||
git checkout -q -b master origin/master
|
git checkout -q -b master origin/master
|
||||||
ynh_ruby_try_bash_extension
|
_ynh_ruby_try_bash_extension
|
||||||
rbenv=$rbenv_install_dir/bin/rbenv
|
rbenv=$RBENV_INSTALL_DIR/bin/rbenv
|
||||||
fi
|
fi
|
||||||
popd
|
popd
|
||||||
else
|
else
|
||||||
echo "Installing rbenv..."
|
echo "Installing rbenv..."
|
||||||
pushd $rbenv_install_dir
|
pushd $RBENV_INSTALL_DIR
|
||||||
git init -q
|
git init -q
|
||||||
git remote add -f -t master origin https://github.com/rbenv/rbenv.git > /dev/null 2>&1
|
git remote add -f -t master origin https://github.com/rbenv/rbenv.git > /dev/null 2>&1
|
||||||
git checkout -q -b master origin/master
|
git checkout -q -b master origin/master
|
||||||
ynh_ruby_try_bash_extension
|
_ynh_ruby_try_bash_extension
|
||||||
rbenv=$rbenv_install_dir/bin/rbenv
|
rbenv=$RBENV_INSTALL_DIR/bin/rbenv
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "${rbenv_install_dir}/plugins"
|
mkdir -p "${RBENV_INSTALL_DIR}/plugins"
|
||||||
|
|
||||||
ruby_build="$(command -v "$rbenv_install_dir"/plugins/*/bin/rbenv-install rbenv-install | head -1)"
|
ruby_build="$(command -v "$RBENV_INSTALL_DIR"/plugins/*/bin/rbenv-install rbenv-install | head -1)"
|
||||||
if [ -n "$ruby_build" ]; then
|
if [ -n "$ruby_build" ]; then
|
||||||
pushd "${ruby_build%/*/*}"
|
pushd "${ruby_build%/*/*}"
|
||||||
if git remote -v 2> /dev/null | grep "https://github.com/rbenv/ruby-build.git"; then
|
if git remote -v 2> /dev/null | grep "https://github.com/rbenv/ruby-build.git"; then
|
||||||
|
@ -108,10 +99,10 @@ ynh_ruby_install () {
|
||||||
popd
|
popd
|
||||||
else
|
else
|
||||||
echo "Installing ruby-build..."
|
echo "Installing ruby-build..."
|
||||||
git clone -q https://github.com/rbenv/ruby-build.git "${rbenv_install_dir}/plugins/ruby-build"
|
git clone -q https://github.com/rbenv/ruby-build.git "${RBENV_INSTALL_DIR}/plugins/ruby-build"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rbenv_alias="$(command -v "$rbenv_install_dir"/plugins/*/bin/rbenv-alias rbenv-alias | head -1)"
|
rbenv_alias="$(command -v "$RBENV_INSTALL_DIR"/plugins/*/bin/rbenv-alias rbenv-alias | head -1)"
|
||||||
if [ -n "$rbenv_alias" ]; then
|
if [ -n "$rbenv_alias" ]; then
|
||||||
pushd "${rbenv_alias%/*/*}"
|
pushd "${rbenv_alias%/*/*}"
|
||||||
if git remote -v 2> /dev/null | grep "https://github.com/tpope/rbenv-aliases.git"; then
|
if git remote -v 2> /dev/null | grep "https://github.com/tpope/rbenv-aliases.git"; then
|
||||||
|
@ -121,10 +112,10 @@ ynh_ruby_install () {
|
||||||
popd
|
popd
|
||||||
else
|
else
|
||||||
echo "Installing rbenv-aliases..."
|
echo "Installing rbenv-aliases..."
|
||||||
git clone -q https://github.com/tpope/rbenv-aliases.git "${rbenv_install_dir}/plugins/rbenv-aliase"
|
git clone -q https://github.com/tpope/rbenv-aliases.git "${RBENV_INSTALL_DIR}/plugins/rbenv-aliase"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rbenv_latest="$(command -v "$rbenv_install_dir"/plugins/*/bin/rbenv-latest rbenv-latest | head -1)"
|
rbenv_latest="$(command -v "$RBENV_INSTALL_DIR"/plugins/*/bin/rbenv-latest rbenv-latest | head -1)"
|
||||||
if [ -n "$rbenv_latest" ]; then
|
if [ -n "$rbenv_latest" ]; then
|
||||||
pushd "${rbenv_latest%/*/*}"
|
pushd "${rbenv_latest%/*/*}"
|
||||||
if git remote -v 2> /dev/null | grep "https://github.com/momo-lab/xxenv-latest.git"; then
|
if git remote -v 2> /dev/null | grep "https://github.com/momo-lab/xxenv-latest.git"; then
|
||||||
|
@ -134,14 +125,14 @@ ynh_ruby_install () {
|
||||||
popd
|
popd
|
||||||
else
|
else
|
||||||
echo "Installing xxenv-latest..."
|
echo "Installing xxenv-latest..."
|
||||||
git clone -q https://github.com/momo-lab/xxenv-latest.git "${rbenv_install_dir}/plugins/xxenv-latest"
|
git clone -q https://github.com/momo-lab/xxenv-latest.git "${RBENV_INSTALL_DIR}/plugins/xxenv-latest"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Enable caching
|
# Enable caching
|
||||||
mkdir -p "${rbenv_install_dir}/cache"
|
mkdir -p "${RBENV_INSTALL_DIR}/cache"
|
||||||
|
|
||||||
# Create shims directory if needed
|
# Create shims directory if needed
|
||||||
mkdir -p "${rbenv_install_dir}/shims"
|
mkdir -p "${RBENV_INSTALL_DIR}/shims"
|
||||||
|
|
||||||
# Restore /usr/local/bin in PATH
|
# Restore /usr/local/bin in PATH
|
||||||
PATH=$CLEAR_PATH
|
PATH=$CLEAR_PATH
|
||||||
|
@ -162,8 +153,7 @@ ynh_ruby_install () {
|
||||||
ruby_version=$final_ruby_version
|
ruby_version=$final_ruby_version
|
||||||
|
|
||||||
# Remove app virtualenv
|
# Remove app virtualenv
|
||||||
if rbenv alias --list | grep --quiet "$app "
|
if rbenv alias --list | grep --quiet "$app "; then
|
||||||
then
|
|
||||||
rbenv alias $app --remove
|
rbenv alias $app --remove
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -175,8 +165,8 @@ ynh_ruby_install () {
|
||||||
|
|
||||||
# Set environment for Ruby users
|
# Set environment for Ruby users
|
||||||
echo "#rbenv
|
echo "#rbenv
|
||||||
export RBENV_ROOT=$rbenv_install_dir
|
export RBENV_ROOT=$RBENV_INSTALL_DIR
|
||||||
export PATH=\"$rbenv_install_dir/bin:$PATH\"
|
export PATH=\"$RBENV_INSTALL_DIR/bin:$PATH\"
|
||||||
eval \"\$(rbenv init -)\"
|
eval \"\$(rbenv init -)\"
|
||||||
#rbenv" > /etc/profile.d/rbenv.sh
|
#rbenv" > /etc/profile.d/rbenv.sh
|
||||||
|
|
||||||
|
@ -188,14 +178,15 @@ eval \"\$(rbenv init -)\"
|
||||||
|
|
||||||
# Remove the version of Ruby used by the app.
|
# Remove the version of Ruby used by the app.
|
||||||
#
|
#
|
||||||
# This helper will also cleanup Ruby versions
|
# This helper will also cleanup unused Ruby versions
|
||||||
#
|
#
|
||||||
# usage: ynh_ruby_remove
|
# usage: ynh_ruby_remove
|
||||||
ynh_ruby_remove() {
|
ynh_ruby_remove() {
|
||||||
local ruby_version=$(ynh_app_setting_get --key=ruby_version)
|
|
||||||
|
[[ -n "${ruby_version:-}" ]] || ynh_die "\$ruby_version should be defined prior to calling ynh_ruby_remove"
|
||||||
|
|
||||||
# Load rbenv path in PATH
|
# Load rbenv path in PATH
|
||||||
local CLEAR_PATH="$rbenv_install_dir/bin:$PATH"
|
local CLEAR_PATH="$RBENV_INSTALL_DIR/bin:$PATH"
|
||||||
|
|
||||||
# Remove /usr/local/bin in PATH in case of Ruby prior installation
|
# Remove /usr/local/bin in PATH in case of Ruby prior installation
|
||||||
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@')
|
||||||
|
@ -211,6 +202,8 @@ ynh_ruby_remove () {
|
||||||
|
|
||||||
# Remove no more needed versions of Ruby used by the app.
|
# Remove no more needed versions of Ruby used by the app.
|
||||||
#
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
# This helper will check what Ruby version are no more required,
|
# This helper will check what Ruby version are no more required,
|
||||||
# and uninstall them
|
# and uninstall them
|
||||||
# If no app uses Ruby, rbenv will be also removed.
|
# If no app uses Ruby, rbenv will be also removed.
|
||||||
|
@ -219,37 +212,32 @@ _ynh_ruby_cleanup () {
|
||||||
# List required Ruby versions
|
# List required Ruby versions
|
||||||
local installed_apps=$(yunohost app list | grep -oP 'id: \K.*$')
|
local installed_apps=$(yunohost app list | grep -oP 'id: \K.*$')
|
||||||
local required_ruby_versions=""
|
local required_ruby_versions=""
|
||||||
for installed_app in $installed_apps
|
for installed_app in $installed_apps; do
|
||||||
do
|
|
||||||
local installed_app_ruby_version=$(ynh_app_setting_get --app=$installed_app --key="ruby_version")
|
local installed_app_ruby_version=$(ynh_app_setting_get --app=$installed_app --key="ruby_version")
|
||||||
if [[ -n "$installed_app_ruby_version" ]]
|
if [[ -n "$installed_app_ruby_version" ]]; then
|
||||||
then
|
|
||||||
required_ruby_versions="${installed_app_ruby_version}\n${required_ruby_versions}"
|
required_ruby_versions="${installed_app_ruby_version}\n${required_ruby_versions}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Remove no more needed Ruby versions
|
# Remove no more needed Ruby versions
|
||||||
local installed_ruby_versions=$(rbenv versions --bare --skip-aliases | grep -Ev '/')
|
local installed_ruby_versions=$(rbenv versions --bare --skip-aliases | grep -Ev '/')
|
||||||
for installed_ruby_version in $installed_ruby_versions
|
for installed_ruby_version in $installed_ruby_versions; do
|
||||||
do
|
if ! echo ${required_ruby_versions} | grep -q "${installed_ruby_version}"; then
|
||||||
if ! echo ${required_ruby_versions} | grep -q "${installed_ruby_version}"
|
|
||||||
then
|
|
||||||
echo "Removing Ruby-$installed_ruby_version"
|
echo "Removing Ruby-$installed_ruby_version"
|
||||||
$rbenv_install_dir/bin/rbenv uninstall --force $installed_ruby_version
|
$RBENV_INSTALL_DIR/bin/rbenv uninstall --force $installed_ruby_version
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# If none Ruby version is required
|
# If none Ruby version is required
|
||||||
if [[ -z "$required_ruby_versions" ]]
|
if [[ -z "$required_ruby_versions" ]]; then
|
||||||
then
|
|
||||||
# Remove rbenv environment configuration
|
# Remove rbenv environment configuration
|
||||||
echo "Removing rbenv"
|
echo "Removing rbenv"
|
||||||
ynh_safe_rm "$rbenv_install_dir"
|
ynh_safe_rm "$RBENV_INSTALL_DIR"
|
||||||
ynh_safe_rm "/etc/profile.d/rbenv.sh"
|
ynh_safe_rm "/etc/profile.d/rbenv.sh"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
ynh_ruby_try_bash_extension() {
|
_ynh_ruby_try_bash_extension() {
|
||||||
if [ -x src/configure ]; then
|
if [ -x src/configure ]; then
|
||||||
src/configure && make -C src 2>&1 || {
|
src/configure && make -C src 2>&1 || {
|
||||||
ynh_print_info "Optional bash extension failed to build, but things will still work normally."
|
ynh_print_info "Optional bash extension failed to build, but things will still work normally."
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
|
|
||||||
# Get an application setting
|
# Get an application setting
|
||||||
#
|
#
|
||||||
# usage: ynh_app_setting_get --app=app --key=key
|
# usage: ynh_app_setting_get --key=key
|
||||||
# | arg: -a, --app= - the application id
|
# | arg: --app= - the application id (global $app by default)
|
||||||
# | arg: -k, --key= - the setting to get
|
# | arg: --key= - the setting to get
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_app_setting_get() {
|
ynh_app_setting_get() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local _globalapp=${app-:}
|
local _globalapp=${app-:}
|
||||||
|
@ -22,12 +20,10 @@ 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 --key=key --value=value
|
||||||
# | arg: -a, --app= - the application id
|
# | arg: --app= - the application id (global $app by default)
|
||||||
# | arg: -k, --key= - the setting name to set
|
# | arg: --key= - the setting name to set
|
||||||
# | arg: -v, --value= - the setting value to set
|
# | arg: --value= - the setting value to set
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_app_setting_set() {
|
ynh_app_setting_set() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local _globalapp=${app-:}
|
local _globalapp=${app-:}
|
||||||
|
@ -42,13 +38,44 @@ ynh_app_setting_set() {
|
||||||
ynh_app_setting "set" "$app" "$key" "$value"
|
ynh_app_setting "set" "$app" "$key" "$value"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Set an application setting but only if the "$key" variable ain't set yet
|
||||||
|
#
|
||||||
|
# Note that it doesn't just define the setting but ALSO define the $foobar variable
|
||||||
|
#
|
||||||
|
# Hence it's meant as a replacement for this legacy overly complex syntax:
|
||||||
|
#
|
||||||
|
# if [ -z "${foo:-}" ]
|
||||||
|
# then
|
||||||
|
# foo="bar"
|
||||||
|
# ynh_app_setting_set --key="foo" --value="$foo"
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# usage: ynh_app_setting_set_default --key=key --value=value
|
||||||
|
# | arg: --app= - the application id (global $app by default)
|
||||||
|
# | arg: --key= - the setting name to set
|
||||||
|
# | arg: --value= - the default setting value to set
|
||||||
|
ynh_app_setting_set_default() {
|
||||||
|
# ============ Argument parsing =============
|
||||||
|
local _globalapp=${app-:}
|
||||||
|
local -A args_array=([a]=app= [k]=key= [v]=value=)
|
||||||
|
local app
|
||||||
|
local key
|
||||||
|
local value
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
app="${app:-$_globalapp}"
|
||||||
|
# ===========================================
|
||||||
|
|
||||||
|
if [ -z "${!key:-}" ]; then
|
||||||
|
eval $key=\$value
|
||||||
|
ynh_app_setting "set" "$app" "$key" "$value"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Delete an application setting
|
# Delete an application setting
|
||||||
#
|
#
|
||||||
# usage: ynh_app_setting_delete --app=app --key=key
|
# usage: ynh_app_setting_delete --key=key
|
||||||
# | arg: -a, --app= - the application id
|
# | arg: --app= - the application id (global $app by default)
|
||||||
# | arg: -k, --key= - the setting to delete
|
# | arg: --key= - the setting to delete
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_app_setting_delete() {
|
ynh_app_setting_delete() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local _globalapp=${app-:}
|
local _globalapp=${app-:}
|
||||||
|
@ -68,6 +95,8 @@ ynh_app_setting_delete() {
|
||||||
# [internal]
|
# [internal]
|
||||||
#
|
#
|
||||||
ynh_app_setting() {
|
ynh_app_setting() {
|
||||||
|
# Trick to only re-enable debugging if it was set before
|
||||||
|
local xtrace_enable=$(set +o | grep xtrace)
|
||||||
set +o xtrace # set +x
|
set +o xtrace # set +x
|
||||||
ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python3 - << EOF
|
ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python3 - << EOF
|
||||||
import os, yaml, sys
|
import os, yaml, sys
|
||||||
|
@ -91,5 +120,16 @@ else:
|
||||||
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
|
||||||
set -o xtrace # set -x
|
eval "$xtrace_enable"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Legacy: auto-convert phpversion to php_version (for consistency with nodejs_version, ruby_version, ...)
|
||||||
|
# This has to be here and not in the "php" code file because ynh_app_setting_set/delete need to be defined @_@
|
||||||
|
if [[ -n "${app:-}" ]] && [[ -n "${phpversion:-}" ]]; then
|
||||||
|
if [[ -z "${php_version:-}" ]]; then
|
||||||
|
php_version=$phpversion
|
||||||
|
ynh_app_setting_set --key=php_version --value=$php_version
|
||||||
|
fi
|
||||||
|
ynh_app_setting_delete --key=phpversion
|
||||||
|
unset phpversion
|
||||||
|
fi
|
||||||
|
|
253
helpers/helpers.v2.1.d/sources
Normal file
253
helpers/helpers.v2.1.d/sources
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Download, check integrity, uncompress and patch upstream sources
|
||||||
|
#
|
||||||
|
# usage: ynh_setup_source --dest_dir=dest_dir [--source_id=source_id] [--keep="file1 file2"] [--full_replace]
|
||||||
|
# | arg: --dest_dir= - Directory where to setup sources
|
||||||
|
# | arg: --source_id= - Name of the source, defaults to `main` (when the sources resource exists in manifest.toml) or (legacy) `app` otherwise
|
||||||
|
# | arg: --keep= - Space-separated list of files/folders that will be backup/restored in $dest_dir, such as a config file you don't want to overwrite. For example 'conf.json secrets.json logs' (no trailing `/` for folders)
|
||||||
|
# | arg: --full_replace= - Remove previous sources before installing new sources (can be 1 or 0, default to 0)
|
||||||
|
#
|
||||||
|
# This helper will read infos from the 'sources' resources in the `manifest.toml` of the app
|
||||||
|
# and expect a structure like:
|
||||||
|
#
|
||||||
|
# ```toml
|
||||||
|
# [resources.sources]
|
||||||
|
# [resources.sources.main]
|
||||||
|
# url = "https://some.address.to/download/the/app/archive"
|
||||||
|
# sha256 = "0123456789abcdef" # The sha256 sum of the asset obtained from the URL
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# (See also the resources documentation which may be more complete?)
|
||||||
|
#
|
||||||
|
# ##### Optional flags in the 'sources' resource
|
||||||
|
#
|
||||||
|
# ```text
|
||||||
|
# format = "tar.gz"/xz/bz2/tar # automatically guessed from the extension of the URL, but can be set explicitly. Will use `tar` to extract
|
||||||
|
# "zip" # automatically guessed from the extension of the URL, but can be set explicitly. Will use `unzip` to extract
|
||||||
|
# "docker" # useful to extract files from an already-built docker image (instead of rebuilding them locally). Will use `docker-image-extract` to extract
|
||||||
|
# "whatever" # an arbitrary value, not really meaningful except to imply that the file won't be extracted
|
||||||
|
#
|
||||||
|
# in_subdir = true # default, there's an intermediate subdir in the archive before accessing the actual files
|
||||||
|
# false # sources are directly in the archive root
|
||||||
|
# n # (special cases) an integer representing a number of subdirs levels to get rid of
|
||||||
|
#
|
||||||
|
# extract = true # default if file is indeed an archive such as .zip, .tar.gz, .tar.bz2, ...
|
||||||
|
# = false # default if file 'format' is not set and the file is not to be extracted because it is not an archive but a script or binary or whatever asset.
|
||||||
|
# # in which case the file will only be `mv`ed to the location possibly renamed using the `rename` value
|
||||||
|
#
|
||||||
|
# rename = "whatever_your_want" # to be used for convenience when `extract` is false and the default name of the file is not practical
|
||||||
|
# platform = "linux/amd64" # (defaults to "linux/$YNH_ARCH") to be used in conjonction with `format = "docker"` to specify which architecture to extract for
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# You may also define assets url and checksum per-architectures such as:
|
||||||
|
# ```toml
|
||||||
|
# [resources.sources]
|
||||||
|
# [resources.sources.main]
|
||||||
|
# amd64.url = "https://some.address.to/download/the/app/archive/when/amd64"
|
||||||
|
# amd64.sha256 = "0123456789abcdef"
|
||||||
|
# armhf.url = "https://some.address.to/download/the/app/archive/when/armhf"
|
||||||
|
# armhf.sha256 = "fedcba9876543210"
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# In which case `ynh_setup_source --dest_dir="$install_dir"` will automatically pick the appropriate source depending on the arch
|
||||||
|
#
|
||||||
|
# The helper will:
|
||||||
|
# - Download the specific URL if there is no local archive
|
||||||
|
# - Check the integrity with the specific sha256 sum
|
||||||
|
# - Uncompress the archive to `$dest_dir`.
|
||||||
|
# - If `in_subdir` is true, the first level directory of the archive will be removed.
|
||||||
|
# - If `in_subdir` is a numeric value, the N first level directories will be removed.
|
||||||
|
# - Patches named `patches/${src_id}/*.patch` will be applied to `$dest_dir`
|
||||||
|
# - Apply sane default permissions (see _ynh_apply_default_permissions)
|
||||||
|
ynh_setup_source() {
|
||||||
|
# ============ Argument parsing =============
|
||||||
|
local -A args_array=([d]=dest_dir= [s]=source_id= [k]=keep= [r]=full_replace)
|
||||||
|
local dest_dir
|
||||||
|
local source_id
|
||||||
|
local keep
|
||||||
|
local full_replace
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
keep="${keep:-}"
|
||||||
|
full_replace="${full_replace:-0}"
|
||||||
|
source_id="${source_id:-main}"
|
||||||
|
# ===========================================
|
||||||
|
|
||||||
|
local sources_json=$(ynh_read_manifest "resources.sources[\"$source_id\"]")
|
||||||
|
if jq -re ".url" <<< "$sources_json"; then
|
||||||
|
local arch_prefix=""
|
||||||
|
else
|
||||||
|
local arch_prefix=".$YNH_ARCH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local src_url="$(jq -r "$arch_prefix.url" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_sum="$(jq -r "$arch_prefix.sha256" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_format="$(jq -r ".format" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_in_subdir="$(jq -r ".in_subdir" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
src_in_subdir=${src_in_subdir:-true}
|
||||||
|
local src_extract="$(jq -r ".extract" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_platform="$(jq -r ".platform" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
local src_rename="$(jq -r ".rename" <<< "$sources_json" | sed 's/^null$//')"
|
||||||
|
|
||||||
|
[[ -n "$src_url" ]] || ynh_die "No URL defined for source $source_id$arch_prefix ?"
|
||||||
|
[[ -n "$src_sum" ]] || ynh_die "No sha256 sum defined for source $source_id$arch_prefix ?"
|
||||||
|
|
||||||
|
if [[ -z "$src_format" ]]; then
|
||||||
|
if [[ "$src_url" =~ ^.*\.zip$ ]] || [[ "$src_url" =~ ^.*/zipball/.*$ ]]; then
|
||||||
|
src_format="zip"
|
||||||
|
elif [[ "$src_url" =~ ^.*\.tar\.gz$ ]] || [[ "$src_url" =~ ^.*\.tgz$ ]] || [[ "$src_url" =~ ^.*/tar\.gz/.*$ ]] || [[ "$src_url" =~ ^.*/tarball/.*$ ]]; then
|
||||||
|
src_format="tar.gz"
|
||||||
|
elif [[ "$src_url" =~ ^.*\.tar\.xz$ ]]; then
|
||||||
|
src_format="tar.xz"
|
||||||
|
elif [[ "$src_url" =~ ^.*\.tar\.bz2$ ]]; then
|
||||||
|
src_format="tar.bz2"
|
||||||
|
elif [[ "$src_url" =~ ^.*\.tar$ ]]; then
|
||||||
|
src_format="tar"
|
||||||
|
elif [[ -z "$src_extract" ]]; then
|
||||||
|
src_extract="false"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
src_format=${src_format:-tar.gz}
|
||||||
|
src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]')
|
||||||
|
src_extract=${src_extract:-true}
|
||||||
|
|
||||||
|
if [[ "$src_extract" != "true" ]] && [[ "$src_extract" != "false" ]]; then
|
||||||
|
ynh_die "For source $source_id, expected either 'true' or 'false' for the extract parameter"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Gotta use this trick with 'dirname' because source_id may contain slashes x_x
|
||||||
|
mkdir -p $(dirname /var/cache/yunohost/download/${YNH_APP_ID}/${source_id})
|
||||||
|
src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${source_id}"
|
||||||
|
|
||||||
|
if [ "$src_format" = "docker" ]; then
|
||||||
|
src_platform="${src_platform:-"linux/$YNH_ARCH"}"
|
||||||
|
else
|
||||||
|
[ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?"
|
||||||
|
|
||||||
|
# If the file was prefetched but somehow doesn't match the sum, rm and redownload it
|
||||||
|
if [ -e "$src_filename" ] && ! echo "${src_sum} ${src_filename}" | sha256sum --check --status; then
|
||||||
|
rm -f "$src_filename"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Only redownload the file if it wasnt prefetched
|
||||||
|
if [ ! -e "$src_filename" ]; then
|
||||||
|
# NB. we have to declare the var as local first,
|
||||||
|
# otherwise 'local foo=$(false) || echo 'pwet'" does'nt work
|
||||||
|
# because local always return 0 ...
|
||||||
|
local out
|
||||||
|
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
||||||
|
out=$(wget --tries 3 --no-dns-cache --timeout 900 --no-verbose --output-document=$src_filename $src_url 2>&1) \
|
||||||
|
|| ynh_die "$out"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check the control sum
|
||||||
|
if ! echo "${src_sum} ${src_filename}" | sha256sum --check --status; then
|
||||||
|
local actual_sum="$(sha256sum ${src_filename} | cut --delimiter=' ' --fields=1)"
|
||||||
|
local actual_size="$(du -hs ${src_filename} | cut --fields=1)"
|
||||||
|
rm -f ${src_filename}
|
||||||
|
ynh_die "Corrupt source for ${src_url}: Expected sha256sum to be ${src_sum} but got ${actual_sum} (size: ${actual_size})."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Keep files to be backup/restored at the end of the helper
|
||||||
|
# Assuming $dest_dir already exists
|
||||||
|
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
||||||
|
if [ -n "$keep" ] && [ -e "$dest_dir" ]; then
|
||||||
|
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
||||||
|
mkdir -p $keep_dir
|
||||||
|
local stuff_to_keep
|
||||||
|
for stuff_to_keep in $keep; do
|
||||||
|
if [ -e "$dest_dir/$stuff_to_keep" ]; then
|
||||||
|
mkdir --parents "$(dirname "$keep_dir/$stuff_to_keep")"
|
||||||
|
cp --archive "$dest_dir/$stuff_to_keep" "$keep_dir/$stuff_to_keep"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$full_replace" -eq 1 ]; then
|
||||||
|
ynh_safe_rm "$dest_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract source into the app dir
|
||||||
|
mkdir --parents "$dest_dir"
|
||||||
|
|
||||||
|
if [[ "$src_extract" == "false" ]]; then
|
||||||
|
if [[ -z "$src_rename" ]]; then
|
||||||
|
mv $src_filename $dest_dir
|
||||||
|
else
|
||||||
|
mv $src_filename $dest_dir/$src_rename
|
||||||
|
fi
|
||||||
|
elif [[ "$src_format" == "docker" ]]; then
|
||||||
|
"$YNH_HELPERS_DIR/vendor/docker-image-extract/docker-image-extract" -p $src_platform -o $dest_dir $src_url 2>&1
|
||||||
|
elif [[ "$src_format" == "zip" ]]; then
|
||||||
|
# Zip format
|
||||||
|
# Using of a temp directory, because unzip doesn't manage --strip-components
|
||||||
|
if $src_in_subdir; then
|
||||||
|
local tmp_dir=$(mktemp --directory)
|
||||||
|
unzip -quo $src_filename -d "$tmp_dir"
|
||||||
|
cp --archive $tmp_dir/*/. "$dest_dir"
|
||||||
|
ynh_safe_rm "$tmp_dir"
|
||||||
|
else
|
||||||
|
unzip -quo $src_filename -d "$dest_dir"
|
||||||
|
fi
|
||||||
|
ynh_safe_rm "$src_filename"
|
||||||
|
else
|
||||||
|
local strip=""
|
||||||
|
if [ "$src_in_subdir" != "false" ]; then
|
||||||
|
if [ "$src_in_subdir" == "true" ]; then
|
||||||
|
local sub_dirs=1
|
||||||
|
else
|
||||||
|
local sub_dirs="$src_in_subdir"
|
||||||
|
fi
|
||||||
|
strip="--strip-components $sub_dirs"
|
||||||
|
fi
|
||||||
|
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz|tar$ ]]; then
|
||||||
|
tar --extract --file=$src_filename --directory="$dest_dir" $strip
|
||||||
|
else
|
||||||
|
ynh_die "Archive format unrecognized."
|
||||||
|
fi
|
||||||
|
ynh_safe_rm "$src_filename"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Apply patches
|
||||||
|
if [ -d "$YNH_APP_BASEDIR/patches/" ]; then
|
||||||
|
local patches_folder=$(realpath "$YNH_APP_BASEDIR/patches/$source_id")
|
||||||
|
pushd "$dest_dir"
|
||||||
|
for patchfile in "$patches_folder/"*.patch; do
|
||||||
|
echo "Applying $patchfile"
|
||||||
|
if ! patch --strip=1 < "$patchfile"; then
|
||||||
|
if ynh_in_ci_tests; then
|
||||||
|
ynh_die "Patch $patchfile failed to apply!"
|
||||||
|
else
|
||||||
|
ynh_print_warn "Warn your packagers /!\\ Patch $patchfile failed to apply"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Keep files to be backup/restored at the end of the helper
|
||||||
|
# Assuming $dest_dir already exists
|
||||||
|
if [ -n "$keep" ]; then
|
||||||
|
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
||||||
|
local stuff_to_keep
|
||||||
|
for stuff_to_keep in $keep; do
|
||||||
|
if [ -e "$keep_dir/$stuff_to_keep" ]; then
|
||||||
|
mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")"
|
||||||
|
|
||||||
|
# We add "--no-target-directory" (short option is -T) to handle the special case
|
||||||
|
# when we "keep" a folder, but then the new setup already contains the same dir (but possibly empty)
|
||||||
|
# in which case a regular "cp" will create a copy of the directory inside the directory ...
|
||||||
|
# resulting in something like /var/www/$app/data/data instead of /var/www/$app/data
|
||||||
|
# cf https://unix.stackexchange.com/q/94831 for a more elaborate explanation on the option
|
||||||
|
cp --archive --no-target-directory "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
||||||
|
|
||||||
|
if [ -n "${install_dir:-}" ] && [ "$dest_dir" == "$install_dir" ]; then
|
||||||
|
_ynh_apply_default_permissions $dest_dir
|
||||||
|
fi
|
||||||
|
}
|
|
@ -3,13 +3,11 @@
|
||||||
# Generate a random string
|
# Generate a random string
|
||||||
#
|
#
|
||||||
# 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: --length= - the string length to generate (default: 24)
|
||||||
# | arg: -f, --filter= - the kind of characters accepted in the output (default: 'A-Za-z0-9')
|
# | arg: --filter= - the kind of characters accepted in the output (default: 'A-Za-z0-9')
|
||||||
# | ret: the generated string
|
# | ret: the generated string
|
||||||
#
|
#
|
||||||
# example: pwd=$(ynh_string_random --length=8)
|
# example: pwd=$(ynh_string_random --length=8)
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_string_random() {
|
ynh_string_random() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([l]=length= [f]=filter=)
|
local -A args_array=([l]=length= [f]=filter=)
|
||||||
|
@ -28,14 +26,12 @@ ynh_string_random() {
|
||||||
# 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 --match=match --replace=replace --file=file
|
# usage: ynh_replace --match=match --replace=replace --file=file
|
||||||
# | arg: -m, --match= - String to be searched and replaced in the file
|
# | arg: --match= - String to be searched and replaced in the file
|
||||||
# | arg: -r, --replace= - String that will replace matches
|
# | arg: --replace= - String that will replace matches
|
||||||
# | arg: -f, --file= - File in which the string will be replaced.
|
# | arg: --file= - File in which the string will be replaced.
|
||||||
#
|
#
|
||||||
# As this helper is based on sed command, regular expressions and references to
|
# As this helper is based on sed command, regular expressions and references to
|
||||||
# sub-expressions can be used (see sed manual page for more information)
|
# sub-expressions can be used (see sed manual page for more information)
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_replace() {
|
ynh_replace() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([m]=match= [r]=replace= [f]=file=)
|
local -A args_array=([m]=match= [r]=replace= [f]=file=)
|
||||||
|
@ -55,18 +51,16 @@ ynh_replace() {
|
||||||
sed --in-place "s${delimit}${match}${delimit}${replace}${delimit}g" "$file"
|
sed --in-place "s${delimit}${match}${delimit}${replace}${delimit}g" "$file"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Substitute/replace a special string by another in a file
|
# Substitute/replace a regex in a file
|
||||||
#
|
#
|
||||||
# usage: ynh_replace_special_string --match=match --replace=replace --file=file
|
# usage: ynh_replace_regex --match=match --replace=replace --file=file
|
||||||
# | arg: -m, --match= - String to be searched and replaced in the file
|
# | arg: --match= - String to be searched and replaced in the file
|
||||||
# | arg: -r, --replace= - String that will replace matches
|
# | arg: --replace= - String that will replace matches
|
||||||
# | arg: -f, --file= - File in which the string will be replaced.
|
# | arg: --file= - File in which the string will be replaced.
|
||||||
#
|
#
|
||||||
# This helper will use ynh_replace, but as you can use special
|
# This helper will use ynh_replace, 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.
|
||||||
#
|
ynh_replace_regex() {
|
||||||
# Requires YunoHost version 2.7.7 or higher.
|
|
||||||
ynh_replace_special_string() {
|
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([m]=match= [r]=replace= [f]=file=)
|
local -A args_array=([m]=match= [r]=replace= [f]=file=)
|
||||||
local match
|
local match
|
||||||
|
@ -91,14 +85,12 @@ ynh_replace_special_string() {
|
||||||
# [packagingv1]
|
# [packagingv1]
|
||||||
#
|
#
|
||||||
# usage: ynh_sanitize_dbid --db_name=name
|
# usage: ynh_sanitize_dbid --db_name=name
|
||||||
# | arg: -n, --db_name= - name to correct/sanitize
|
# | arg: --db_name= - name to correct/sanitize
|
||||||
# | ret: the corrected name
|
# | ret: the corrected name
|
||||||
#
|
#
|
||||||
# example: dbname=$(ynh_sanitize_dbid $app)
|
# example: dbname=$(ynh_sanitize_dbid $app)
|
||||||
#
|
#
|
||||||
# Underscorify the string (replace - and . by _)
|
# Underscorify the string (replace - and . by _)
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_sanitize_dbid() {
|
ynh_sanitize_dbid() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([n]=db_name=)
|
local -A args_array=([n]=db_name=)
|
||||||
|
@ -123,8 +115,6 @@ ynh_sanitize_dbid() {
|
||||||
# ynh_normalize_url_path / # -> /
|
# ynh_normalize_url_path / # -> /
|
||||||
#
|
#
|
||||||
# usage: ynh_normalize_url_path path_to_normalize
|
# usage: ynh_normalize_url_path path_to_normalize
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_normalize_url_path() {
|
ynh_normalize_url_path() {
|
||||||
local path_url=$1
|
local path_url=$1
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,13 @@
|
||||||
# Create a dedicated systemd config
|
# Create a dedicated systemd config
|
||||||
#
|
#
|
||||||
# usage: ynh_config_add_systemd [--service=service] [--template=template]
|
# usage: ynh_config_add_systemd [--service=service] [--template=template]
|
||||||
# | arg: -s, --service= - Service name (optionnal, `$app` by default)
|
# | arg: --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: --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`.
|
||||||
#
|
#
|
||||||
# See the documentation of `ynh_config_add` for a description of the template
|
# See the documentation of `ynh_config_add` for a description of the template
|
||||||
# format and how placeholders are replaced with actual variables.
|
# format and how placeholders are replaced with actual variables.
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_config_add_systemd() {
|
ynh_config_add_systemd() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([s]=service= [t]=template=)
|
local -A args_array=([s]=service= [t]=template=)
|
||||||
|
@ -45,14 +43,12 @@ ynh_config_remove_systemd() {
|
||||||
# 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_systemctl [--service=service] [--action=action] [ [--wait_until="line to match"] [--log_path=log_path] [--timeout=300] [--length=20] ]
|
# usage: ynh_systemctl [--service=service] [--action=action] [ [--wait_until="line to match"] [--log_path=log_path] [--timeout=300] [--length=20] ]
|
||||||
# | arg: -n, --service= - Name of the service to start. Default : `$app`
|
# | arg: --service= - Name of the service to start. Default : `$app`
|
||||||
# | arg: -a, --action= - Action to perform with systemctl. Default: start
|
# | arg: --action= - Action to perform with systemctl. Default: start
|
||||||
# | arg: -w, --wait_until= - The pattern to find in the log to attest the service is effectively fully started.
|
# | arg: --wait_until= - The pattern to find in the log to attest the service is effectively fully started.
|
||||||
# | arg: -p, --log_path= - Log file - Path to the log file. Default : `/var/log/$app/$app.log`
|
# | arg: --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: --timeout= - Timeout - The maximum time to wait before ending the watching. Default : 60 seconds.
|
||||||
# | arg: -e, --length= - Length of the error log displayed for debugging : Default : 20
|
# | arg: --length= - Length of the error log displayed for debugging : Default : 20
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
|
||||||
ynh_systemctl() {
|
ynh_systemctl() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([n]=service= [a]=action= [w]=wait_until= [p]=log_path= [t]=timeout= [e]=length=)
|
local -A args_array=([n]=service= [a]=action= [w]=wait_until= [p]=log_path= [t]=timeout= [e]=length=)
|
||||||
|
@ -68,9 +64,14 @@ ynh_systemctl() {
|
||||||
wait_until=${wait_until:-}
|
wait_until=${wait_until:-}
|
||||||
length=${length:-20}
|
length=${length:-20}
|
||||||
log_path="${log_path:-/var/log/$service/$service.log}"
|
log_path="${log_path:-/var/log/$service/$service.log}"
|
||||||
timeout=${timeout:-300}
|
timeout=${timeout:-60}
|
||||||
# ===========================================
|
# ===========================================
|
||||||
|
|
||||||
|
# On CI, use length=100 because it's sometime hell to debug otherwise for super-long output
|
||||||
|
if ynh_in_ci_tests && [ $length -le 20 ]; then
|
||||||
|
length=100
|
||||||
|
fi
|
||||||
|
|
||||||
# Manage case of service already stopped
|
# Manage case of service already stopped
|
||||||
if [ "$action" == "stop" ] && ! systemctl is-active --quiet $service; then
|
if [ "$action" == "stop" ] && ! systemctl is-active --quiet $service; then
|
||||||
return 0
|
return 0
|
||||||
|
@ -114,7 +115,7 @@ ynh_systemctl() {
|
||||||
|
|
||||||
# Start the timeout and try to find wait_until
|
# Start the timeout and try to find wait_until
|
||||||
if [[ -n "${wait_until:-}" ]]; then
|
if [[ -n "${wait_until:-}" ]]; then
|
||||||
set +x
|
set +o xtrace # set +x
|
||||||
local i=0
|
local i=0
|
||||||
local starttime=$(date +%s)
|
local starttime=$(date +%s)
|
||||||
for i in $(seq 1 $timeout); do
|
for i in $(seq 1 $timeout); do
|
||||||
|
@ -137,14 +138,13 @@ ynh_systemctl() {
|
||||||
# Also check the timeout using actual timestamp, because sometimes for some reason,
|
# Also check the timeout using actual timestamp, because sometimes for some reason,
|
||||||
# journalctl may take a huge time to run, and we end up waiting literally an entire hour
|
# journalctl may take a huge time to run, and we end up waiting literally an entire hour
|
||||||
# instead of 5 min ...
|
# instead of 5 min ...
|
||||||
if [[ "$(( $(date +%s) - $starttime))" -gt "$timeout" ]]
|
if [[ "$(($(date +%s) - $starttime))" -gt "$timeout" ]]; then
|
||||||
then
|
|
||||||
i=$timeout
|
i=$timeout
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
set -x
|
set -o xtrace # set -x
|
||||||
if [ $i -ge 3 ]; then
|
if [ $i -ge 3 ]; then
|
||||||
echo "" >&2
|
echo "" >&2
|
||||||
fi
|
fi
|
||||||
|
@ -156,6 +156,12 @@ ynh_systemctl() {
|
||||||
ynh_print_warn "==="
|
ynh_print_warn "==="
|
||||||
tail --lines=$length "$log_path" >&2
|
tail --lines=$length "$log_path" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# If we tried to reload/start/restart the service but systemctl consider it to be still inactive/broken, then handle it as a failure
|
||||||
|
if ([ "$action" == "reload" ] || [ "$action" == "start" ] || [ "$action" == "restart" ]) && ! systemctl --quiet is-active $service; then
|
||||||
|
_ynh_clean_check_starting
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
_ynh_clean_check_starting
|
_ynh_clean_check_starting
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,66 +1,10 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Check if a YunoHost user exists
|
|
||||||
#
|
|
||||||
# usage: ynh_user_exists --username=username
|
|
||||||
# | arg: -u, --username= - the username to check
|
|
||||||
# | ret: 0 if the user exists, 1 otherwise.
|
|
||||||
#
|
|
||||||
# example: ynh_user_exists 'toto' || echo "User does not exist"
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_user_exists() {
|
|
||||||
# ============ Argument parsing =============
|
|
||||||
local -A args_array=([u]=username=)
|
|
||||||
local username
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
# ===========================================
|
|
||||||
|
|
||||||
yunohost user list --output-as json --quiet | jq -e ".users.\"${username}\"" >/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Retrieve a YunoHost user information
|
|
||||||
#
|
|
||||||
# usage: ynh_user_get_info --username=username --key=key
|
|
||||||
# | arg: -u, --username= - the username to retrieve info from
|
|
||||||
# | arg: -k, --key= - the key to retrieve
|
|
||||||
# | ret: the value associate to that key
|
|
||||||
#
|
|
||||||
# example: mail=$(ynh_user_get_info --username="toto" --key=mail)
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_user_get_info() {
|
|
||||||
# ============ Argument parsing =============
|
|
||||||
local -A args_array=([u]=username= [k]=key=)
|
|
||||||
local username
|
|
||||||
local key
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
# ===========================================
|
|
||||||
|
|
||||||
yunohost user info "$username" --output-as json --quiet | jq -r ".$key"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the list of YunoHost users
|
|
||||||
#
|
|
||||||
# usage: ynh_user_list
|
|
||||||
# | ret: one username per line as strings
|
|
||||||
#
|
|
||||||
# example: for u in $(ynh_user_list); do ... ; done
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.4.0 or higher.
|
|
||||||
ynh_user_list() {
|
|
||||||
yunohost user list --output-as json --quiet | jq -r ".users | keys[]"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if a user exists on the system
|
# Check if a user exists on the system
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_system_user_exists --username=username
|
# usage: ynh_system_user_exists --username=username
|
||||||
# | arg: -u, --username= - the username to check
|
# | arg: --username= - the username to check
|
||||||
# | ret: 0 if the user exists, 1 otherwise.
|
# | ret: 0 if the user exists, 1 otherwise.
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_system_user_exists() {
|
ynh_system_user_exists() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([u]=username=)
|
local -A args_array=([u]=username=)
|
||||||
|
@ -73,13 +17,9 @@ ynh_system_user_exists() {
|
||||||
|
|
||||||
# Check if a group exists on the system
|
# Check if a group exists on the system
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_system_group_exists --group=group
|
# usage: ynh_system_group_exists --group=group
|
||||||
# | arg: -g, --group= - the group to check
|
# | arg: --group= - the group to check
|
||||||
# | ret: 0 if the group exists, 1 otherwise.
|
# | ret: 0 if the group exists, 1 otherwise.
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0.2 or higher.
|
|
||||||
ynh_system_group_exists() {
|
ynh_system_group_exists() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([g]=group=)
|
local -A args_array=([g]=group=)
|
||||||
|
@ -92,13 +32,11 @@ ynh_system_group_exists() {
|
||||||
|
|
||||||
# Create a system user
|
# Create a system user
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# usage: ynh_system_user_create --username=user_name [--home_dir=home_dir] [--use_shell] [--groups="group1 group2"]
|
# usage: ynh_system_user_create --username=user_name [--home_dir=home_dir] [--use_shell] [--groups="group1 group2"]
|
||||||
# | arg: -u, --username= - Name of the system user that will be create
|
# | arg: --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: --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: --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: -g, --groups - Add the user to system groups. Typically meant to add the user to the ssh.app / sftp.app group (e.g. for borgserver, my_webapp)
|
# | arg: --groups - Add the user to system groups. Typically meant to add the user to the ssh.app / sftp.app group (e.g. for borgserver, my_webapp)
|
||||||
#
|
#
|
||||||
# Create a nextcloud user with no home directory and /usr/sbin/nologin login shell (hence no login capability) :
|
# Create a nextcloud user with no home directory and /usr/sbin/nologin login shell (hence no login capability) :
|
||||||
# ```
|
# ```
|
||||||
|
@ -108,8 +46,6 @@ 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
|
||||||
# ```
|
# ```
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_system_user_create() {
|
ynh_system_user_create() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([u]=username= [h]=home_dir= [s]=use_shell [g]=groups=)
|
local -A args_array=([u]=username= [h]=home_dir= [s]=use_shell [g]=groups=)
|
||||||
|
@ -146,12 +82,8 @@ ynh_system_user_create() {
|
||||||
|
|
||||||
# Delete a system user
|
# Delete a system user
|
||||||
#
|
#
|
||||||
# [packagingv1]
|
|
||||||
#
|
|
||||||
# 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: --username= - Name of the system user that will be create
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_system_user_delete() {
|
ynh_system_user_delete() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([u]=username=)
|
local -A args_array=([u]=username=)
|
||||||
|
@ -171,12 +103,3 @@ ynh_system_user_delete() {
|
||||||
delgroup $username
|
delgroup $username
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute a command after sudoing as $app
|
|
||||||
#
|
|
||||||
# Note that exported bash env variables are kept (using -E option of sudo)
|
|
||||||
#
|
|
||||||
# usage: ynh_exec_as_app COMMAND [ARG ...]
|
|
||||||
ynh_exec_as_app() {
|
|
||||||
sudo -E -u"$app" "$@"
|
|
||||||
}
|
|
|
@ -3,75 +3,44 @@
|
||||||
# Create a dedicated config file from a template
|
# Create a dedicated config file from a template
|
||||||
#
|
#
|
||||||
# usage: ynh_config_add --template="template" --destination="destination"
|
# usage: ynh_config_add --template="template" --destination="destination"
|
||||||
# | arg: -t, --template= - Template config file to use
|
# | arg: --template= - Template config file to use
|
||||||
# | arg: -d, --destination= - Destination of the config file
|
# | arg: --destination= - Destination of the config file
|
||||||
# | arg: -j, --jinja - Use jinja template instead of legacy __MY_VAR__
|
# | arg: --jinja - Use jinja template instead of the simple `__MY_VAR__` templating format
|
||||||
#
|
#
|
||||||
# examples:
|
# examples:
|
||||||
# ynh_config_add --template=".env" --destination="$install_dir/.env" use the template file "../conf/.env"
|
# ynh_add_config --template=".env" --destination="$install_dir/.env" # (use the template file "conf/.env" from the app's package)
|
||||||
# ynh_config_add --jinja --template="config.j2" --destination="$install_dir/config" use the template file "../conf/config.j2"
|
# ynh_add_config --jinja --template="config.j2" --destination="$install_dir/config" # (use the template file "conf/config.j2" from the app's package)
|
||||||
# ynh_config_add --template="/etc/nginx/sites-available/default" --destination="etc/nginx/sites-available/mydomain.conf"
|
|
||||||
#
|
#
|
||||||
##
|
# The template can be 1) the name of a file in the `conf` directory of
|
||||||
## How it works in "legacy" mode
|
# the app, 2) a relative path or 3) an absolute path.
|
||||||
##
|
|
||||||
# The template can be by default the name of a file in the conf directory
|
|
||||||
# of a YunoHost Package, a relative path or an absolute path.
|
|
||||||
#
|
#
|
||||||
# The helper will use the template `template` to generate a config file
|
# This applies a simple templating format which covers a good 95% of cases,
|
||||||
# `destination` by replacing the following keywords with global variables
|
# where patterns like `__FOO__` are replaced by the bash variable `$foo`, for example:
|
||||||
# that should be defined before calling this helper :
|
# `__DOMAIN__` by `$domain`
|
||||||
# ```
|
# `__PATH__` by `$path`
|
||||||
# __USER__ by $app
|
# `__APP__` by `$app`
|
||||||
# __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH
|
# `__VAR_1__` by `$var_1`
|
||||||
# ```
|
# `__VAR_2__` by `$var_2`
|
||||||
# And any dynamic variables that should be defined before calling this helper like:
|
|
||||||
# ```
|
|
||||||
# __DOMAIN__ by $domain
|
|
||||||
# __PATH__ by $path
|
|
||||||
# __APP__ by $app
|
|
||||||
# __VAR_1__ by $var_1
|
|
||||||
# __VAR_2__ by $var_2
|
|
||||||
# ```
|
|
||||||
#
|
#
|
||||||
##
|
# Special case for `__PATH__/` which is replaced by `/` instead of `//` if `$path` is `/`
|
||||||
## When --jinja is enabled
|
|
||||||
##
|
|
||||||
# For a full documentation of the template you can refer to: https://jinja.palletsprojects.com/en/3.1.x/templates/
|
|
||||||
# In Yunohost context there are no really some specificity except that all variable passed are of type string.
|
|
||||||
# So here are some example of recommended usage:
|
|
||||||
#
|
#
|
||||||
# If you need a conditional block
|
# ##### When --jinja is enabled
|
||||||
#
|
#
|
||||||
# {% if should_my_block_be_shown == 'true' %}
|
# This option is meant for advanced use-cases where the "simple" templating
|
||||||
# ...
|
# mode ain't enough because you need conditional blocks or loops.
|
||||||
# {% endif %}
|
|
||||||
#
|
#
|
||||||
# or
|
# For a full documentation of jinja's syntax you can refer to:
|
||||||
|
# https://jinja.palletsprojects.com/en/3.1.x/templates/
|
||||||
#
|
#
|
||||||
# {% if should_my_block_be_shown == '1' %}
|
# Note that in YunoHost context, all variables are from shell variables and therefore are strings
|
||||||
# ...
|
|
||||||
# {% endif %}
|
|
||||||
#
|
#
|
||||||
# If you need to iterate with loop:
|
# ##### Keeping track of manual changes by the admin
|
||||||
#
|
|
||||||
# {% for yolo in var_with_multiline_value.splitlines() %}
|
|
||||||
# ...
|
|
||||||
# {% endfor %}
|
|
||||||
#
|
|
||||||
# or
|
|
||||||
#
|
|
||||||
# {% for jail in my_var_with_coma.split(',') %}
|
|
||||||
# ...
|
|
||||||
# {% endfor %}
|
|
||||||
#
|
#
|
||||||
# The helper will verify the checksum and backup the destination file
|
# The helper will verify the checksum and backup the destination file
|
||||||
# if it's different before applying the new template.
|
# if it's different before applying the new template.
|
||||||
#
|
#
|
||||||
# And it will calculate and store the destination file checksum
|
# And it will calculate and store the destination file checksum
|
||||||
# into the app settings when configuration is done.
|
# into the app settings when configuration is done.
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_config_add() {
|
ynh_config_add() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([t]=template= [d]=destination= [j]=jinja)
|
local -A args_array=([t]=template= [d]=destination= [j]=jinja)
|
||||||
|
@ -101,8 +70,7 @@ ynh_config_add() {
|
||||||
chmod 640 $destination
|
chmod 640 $destination
|
||||||
_ynh_apply_default_permissions $destination
|
_ynh_apply_default_permissions $destination
|
||||||
|
|
||||||
if [[ "$jinja" == 1 ]]
|
if [[ "$jinja" == 1 ]]; then
|
||||||
then
|
|
||||||
# This is ran in a subshell such that the "export" does not "contaminate" the main process
|
# This is ran in a subshell such that the "export" does not "contaminate" the main process
|
||||||
(
|
(
|
||||||
export $(compgen -v)
|
export $(compgen -v)
|
||||||
|
@ -110,61 +78,41 @@ ynh_config_add() {
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
cp -f "$template_path" "$destination"
|
cp -f "$template_path" "$destination"
|
||||||
ynh_replace_vars --file="$destination"
|
_ynh_replace_vars "$destination"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ynh_store_file_checksum "$destination"
|
ynh_store_file_checksum "$destination"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Replace variables in a file
|
# Replace `__FOO__` patterns in file with bash variable `$foo`
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal]
|
||||||
#
|
#
|
||||||
# usage: ynh_replace_vars --file="file"
|
# usage: ynh_replace_vars "/path/to/file"
|
||||||
# | arg: -f, --file= - File where to replace variables
|
# | arg: /path/to/file - File where to replace variables
|
||||||
#
|
#
|
||||||
# The helper will replace the following keywords with global variables
|
# This applies a simple templating format which covers a good 95% of cases,
|
||||||
# that should be defined before calling this helper :
|
# where patterns like `__FOO__` are replaced by the bash variable `$foo`, for example:
|
||||||
# __PATH__ by $path
|
# `__DOMAIN__` by `$domain`
|
||||||
# __PATH__/ by $path/ if $path != /, or just / otherwise (instead of //)
|
# `__PATH__` by `$path`
|
||||||
# __USER__ by $app
|
# `__APP__` by `$app`
|
||||||
# __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH
|
# `__VAR_1__` by `$var_1`
|
||||||
|
# `__VAR_2__` by `$var_2`
|
||||||
#
|
#
|
||||||
# And any dynamic variables that should be defined before calling this helper like:
|
# Special case for `__PATH__/` which is replaced by `/` instead of `//` if `$path` is `/`
|
||||||
# __DOMAIN__ by $domain
|
_ynh_replace_vars() {
|
||||||
# __APP__ by $app
|
local file=$1
|
||||||
# __VAR_1__ by $var_1
|
|
||||||
# __VAR_2__ by $var_2
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_replace_vars() {
|
|
||||||
# ============ Argument parsing =============
|
|
||||||
local -A args_array=([f]=file=)
|
|
||||||
local file
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
# ===========================================
|
|
||||||
|
|
||||||
# Replace specific YunoHost variables
|
# List unique (__ __) variables in $file
|
||||||
if test -n "${path:-}"; then
|
|
||||||
# path_slash_less is path, or a blank value if path is only '/'
|
|
||||||
local path_slash_less=${path%/}
|
|
||||||
ynh_replace --match="__PATH__/" --replace="$path_slash_less/" --file="$file"
|
|
||||||
ynh_replace --match="__PATH__" --replace="$path" --file="$file"
|
|
||||||
fi
|
|
||||||
if test -n "${app:-}"; then
|
|
||||||
ynh_replace --match="__USER__" --replace="$app" --file="$file"
|
|
||||||
fi
|
|
||||||
if test -n "${ynh_node_load_PATH:-}"; then
|
|
||||||
ynh_replace --match="__YNH_NODE_LOAD_PATH__" --replace="$ynh_node_load_PATH" --file="$file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Replace others variables
|
|
||||||
|
|
||||||
# List other unique (__ __) variables in $file
|
|
||||||
local uniques_vars=($(grep -oP '__[A-Z0-9]+?[A-Z0-9_]*?[A-Z0-9]*?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g"))
|
local uniques_vars=($(grep -oP '__[A-Z0-9]+?[A-Z0-9_]*?[A-Z0-9]*?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g"))
|
||||||
|
|
||||||
set +o xtrace # set +x
|
set +o xtrace # set +x
|
||||||
|
|
||||||
|
# Specific trick to make sure that __PATH__/ doesn't end up in "//" if $path=/
|
||||||
|
if [[ "${path:-}" == "/" ]] && grep -q '__PATH__/' $file; then
|
||||||
|
sed --in-place "s@__PATH__/@/@g" "$file"
|
||||||
|
fi
|
||||||
|
|
||||||
# Do the replacement
|
# Do the replacement
|
||||||
local delimit=@
|
local delimit=@
|
||||||
for one_var in "${uniques_vars[@]}"; do
|
for one_var in "${uniques_vars[@]}"; do
|
||||||
|
@ -191,9 +139,9 @@ ynh_replace_vars() {
|
||||||
# Get a value from heterogeneous file (yaml, json, php, python...)
|
# Get a value from heterogeneous file (yaml, json, php, python...)
|
||||||
#
|
#
|
||||||
# usage: ynh_read_var_in_file --file=PATH --key=KEY
|
# usage: ynh_read_var_in_file --file=PATH --key=KEY
|
||||||
# | arg: -f, --file= - the path to the file
|
# | arg: --file= - the path to the file
|
||||||
# | arg: -k, --key= - the key to get
|
# | arg: --key= - the key to get
|
||||||
# | arg: -a, --after= - the line just before the key (in case of multiple lines with the name of the key in the file)
|
# | arg: --after= - the line just before the key (in case of multiple lines with the name of the key in the file)
|
||||||
#
|
#
|
||||||
# This helpers match several var affectation use case in several languages
|
# This helpers match several var affectation use case in several languages
|
||||||
# We don't use jq or equivalent to keep comments and blank space in files
|
# We don't use jq or equivalent to keep comments and blank space in files
|
||||||
|
@ -220,8 +168,6 @@ ynh_replace_vars() {
|
||||||
# USER = 8102
|
# USER = 8102
|
||||||
# user = 'https://donate.local'
|
# user = 'https://donate.local'
|
||||||
# CUSTOM['user'] = 'YunoHost'
|
# CUSTOM['user'] = 'YunoHost'
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.3 or higher.
|
|
||||||
ynh_read_var_in_file() {
|
ynh_read_var_in_file() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([f]=file= [k]=key= [a]=after=)
|
local -A args_array=([f]=file= [k]=key= [a]=after=)
|
||||||
|
@ -293,12 +239,10 @@ ynh_read_var_in_file() {
|
||||||
# Set a value into heterogeneous file (yaml, json, php, python...)
|
# Set a value into heterogeneous file (yaml, json, php, python...)
|
||||||
#
|
#
|
||||||
# usage: ynh_write_var_in_file --file=PATH --key=KEY --value=VALUE
|
# usage: ynh_write_var_in_file --file=PATH --key=KEY --value=VALUE
|
||||||
# | arg: -f, --file= - the path to the file
|
# | arg: --file= - the path to the file
|
||||||
# | arg: -k, --key= - the key to set
|
# | arg: --key= - the key to set
|
||||||
# | arg: -v, --value= - the value to set
|
# | arg: --value= - the value to set
|
||||||
# | arg: -a, --after= - the line just before the key (in case of multiple lines with the name of the key in the file)
|
# | arg: --after= - the line just before the key (in case of multiple lines with the name of the key in the file)
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.3 or higher.
|
|
||||||
ynh_write_var_in_file() {
|
ynh_write_var_in_file() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([f]=file= [k]=key= [v]=value= [a]=after=)
|
local -A args_array=([f]=file= [k]=key= [v]=value= [a]=after=)
|
||||||
|
|
|
@ -6,24 +6,10 @@ YNH_APP_BASEDIR=${YNH_APP_BASEDIR:-$(realpath ..)}
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal]
|
||||||
#
|
#
|
||||||
# usage:
|
|
||||||
# ynh_exit_properly is used only by the helper ynh_abort_if_errors.
|
|
||||||
# You should not use it directly.
|
|
||||||
# Instead, add to your script:
|
|
||||||
# ynh_clean_setup () {
|
|
||||||
# instructions...
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# This function provide a way to clean some residual of installation that not managed by remove 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 [[ "${YNH_APP_ACTION:-}" =~ ^install$|^upgrade$|^restore$ ]]
|
if [[ "${YNH_APP_ACTION:-}" =~ ^install$|^upgrade$|^restore$ ]]; then
|
||||||
then
|
|
||||||
rm -rf "/var/cache/yunohost/download/"
|
rm -rf "/var/cache/yunohost/download/"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -39,10 +25,6 @@ ynh_exit_properly() {
|
||||||
# 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
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
# Exit with error status
|
# Exit with error status
|
||||||
# We don't call ynh_die basically to avoid unecessary 10-ish
|
# We don't call ynh_die basically to avoid unecessary 10-ish
|
||||||
# debug lines about parsing args and stuff just to exit 1..
|
# debug lines about parsing args and stuff just to exit 1..
|
||||||
|
@ -57,9 +39,6 @@ ynh_exit_properly() {
|
||||||
#
|
#
|
||||||
# This configure the rest of the script execution such that, if an error occurs
|
# This configure the rest of the script execution such that, if an error occurs
|
||||||
# or if an empty variable is used, the execution of the script stops immediately
|
# or if an empty variable is used, the execution of the script stops immediately
|
||||||
# and a call to `ynh_clean_setup` is triggered if it has been defined by your script.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_abort_if_errors() {
|
ynh_abort_if_errors() {
|
||||||
set -o errexit # set -e; Exit if a command fail
|
set -o errexit # set -e; Exit if a command fail
|
||||||
set -o nounset # set -u; And if a variable is used unset
|
set -o nounset # set -u; And if a variable is used unset
|
||||||
|
@ -67,279 +46,17 @@ ynh_abort_if_errors() {
|
||||||
}
|
}
|
||||||
|
|
||||||
# When running an app script, auto-enable ynh_abort_if_errors except for remove script
|
# When running an app script, auto-enable ynh_abort_if_errors except for remove script
|
||||||
if [[ "${YNH_CONTEXT:-}" != "regenconf" ]] && [[ "${YNH_APP_ACTION}" != "remove" ]]
|
if [[ "${YNH_CONTEXT:-}" != "regenconf" ]] && [[ "${YNH_APP_ACTION}" != "remove" ]]; then
|
||||||
then
|
|
||||||
ynh_abort_if_errors
|
ynh_abort_if_errors
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Download, check integrity, uncompress and patch upstream sources
|
# Execute a command after sudoing as $app
|
||||||
#
|
#
|
||||||
# usage: ynh_setup_source --dest_dir=dest_dir [--source_id=source_id] [--keep="file1 file2"] [--full_replace]
|
# Note that the $PATH variable is preserved (using --preserve-env=PATH)
|
||||||
# | arg: -d, --dest_dir= - Directory where to setup sources
|
|
||||||
# | arg: -s, --source_id= - Name of the source, defaults to `main` (when the sources resource exists in manifest.toml) or (legacy) `app` otherwise
|
|
||||||
# | arg: -k, --keep= - Space-separated list of files/folders that will be backup/restored in $dest_dir, such as a config file you don't want to overwrite. For example 'conf.json secrets.json logs' (no trailing `/` for folders)
|
|
||||||
# | arg: -r, --full_replace= - Remove previous sources before installing new sources (can be 1 or 0, default to 0)
|
|
||||||
#
|
#
|
||||||
# #### New 'sources' resources
|
# usage: ynh_exec_as_app COMMAND [ARG ...]
|
||||||
#
|
ynh_exec_as_app() {
|
||||||
# (See also the resources documentation which may be more complete?)
|
sudo --preserve-env=PATH -u "$app" "$@"
|
||||||
#
|
|
||||||
# This helper will read infos from the 'sources' resources in the manifest.toml of the app
|
|
||||||
# and expect a structure like:
|
|
||||||
#
|
|
||||||
# ```toml
|
|
||||||
# [resources.sources]
|
|
||||||
# [resources.sources.main]
|
|
||||||
# url = "https://some.address.to/download/the/app/archive"
|
|
||||||
# sha256 = "0123456789abcdef" # The sha256 sum of the asset obtained from the URL
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# ##### Optional flags
|
|
||||||
#
|
|
||||||
# ```text
|
|
||||||
# format = "tar.gz"/xz/bz2 # automatically guessed from the extension of the URL, but can be set explicitly. Will use `tar` to extract
|
|
||||||
# "zip" # automatically guessed from the extension of the URL, but can be set explicitly. Will use `unzip` to extract
|
|
||||||
# "docker" # useful to extract files from an already-built docker image (instead of rebuilding them locally). Will use `docker-image-extract` to extract
|
|
||||||
# "whatever" # an arbitrary value, not really meaningful except to imply that the file won't be extracted
|
|
||||||
#
|
|
||||||
# in_subdir = true # default, there's an intermediate subdir in the archive before accessing the actual files
|
|
||||||
# false # sources are directly in the archive root
|
|
||||||
# n # (special cases) an integer representing a number of subdirs levels to get rid of
|
|
||||||
#
|
|
||||||
# extract = true # default if file is indeed an archive such as .zip, .tar.gz, .tar.bz2, ...
|
|
||||||
# = false # default if file 'format' is not set and the file is not to be extracted because it is not an archive but a script or binary or whatever asset.
|
|
||||||
# # in which case the file will only be `mv`ed to the location possibly renamed using the `rename` value
|
|
||||||
#
|
|
||||||
# rename = "whatever_your_want" # to be used for convenience when `extract` is false and the default name of the file is not practical
|
|
||||||
# platform = "linux/amd64" # (defaults to "linux/$YNH_ARCH") to be used in conjonction with `format = "docker"` to specify which architecture to extract for
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# You may also define assets url and checksum per-architectures such as:
|
|
||||||
# ```toml
|
|
||||||
# [resources.sources]
|
|
||||||
# [resources.sources.main]
|
|
||||||
# amd64.url = "https://some.address.to/download/the/app/archive/when/amd64"
|
|
||||||
# amd64.sha256 = "0123456789abcdef"
|
|
||||||
# armhf.url = "https://some.address.to/download/the/app/archive/when/armhf"
|
|
||||||
# armhf.sha256 = "fedcba9876543210"
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# In which case ynh_setup_source --dest_dir="$install_dir" will automatically pick the appropriate source depending on the arch
|
|
||||||
#
|
|
||||||
# The helper will:
|
|
||||||
# - Download the specific URL if there is no local archive
|
|
||||||
# - Check the integrity with the specific sha256 sum
|
|
||||||
# - Uncompress the archive to `$dest_dir`.
|
|
||||||
# - If `in_subdir` is true, the first level directory of the archive will be removed.
|
|
||||||
# - If `in_subdir` is a numeric value, the N first level directories will be removed.
|
|
||||||
# - Patches named `patches/${src_id}-*.patch` will be applied to `$dest_dir`
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_setup_source() {
|
|
||||||
# ============ Argument parsing =============
|
|
||||||
local -A args_array=([d]=dest_dir= [s]=source_id= [k]=keep= [r]=full_replace)
|
|
||||||
local dest_dir
|
|
||||||
local source_id
|
|
||||||
local keep
|
|
||||||
local full_replace
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
keep="${keep:-}"
|
|
||||||
full_replace="${full_replace:-0}"
|
|
||||||
source_id="${source_id:-main}"
|
|
||||||
# ===========================================
|
|
||||||
|
|
||||||
local sources_json=$(ynh_read_manifest "resources.sources[\"$source_id\"]")
|
|
||||||
if jq -re ".url" <<< "$sources_json"
|
|
||||||
then
|
|
||||||
local arch_prefix=""
|
|
||||||
else
|
|
||||||
local arch_prefix=".$YNH_ARCH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
local src_url="$(jq -r "$arch_prefix.url" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_sum="$(jq -r "$arch_prefix.sha256" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_sumprg="sha256sum"
|
|
||||||
local src_format="$(jq -r ".format" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_in_subdir="$(jq -r ".in_subdir" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
src_in_subdir=${src_in_subdir:-true}
|
|
||||||
local src_extract="$(jq -r ".extract" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_platform="$(jq -r ".platform" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
local src_rename="$(jq -r ".rename" <<< "$sources_json" | sed 's/^null$//')"
|
|
||||||
|
|
||||||
[[ -n "$src_url" ]] || ynh_die "No URL defined for source $source_id$arch_prefix ?"
|
|
||||||
[[ -n "$src_sum" ]] || ynh_die "No sha256 sum defined for source $source_id$arch_prefix ?"
|
|
||||||
|
|
||||||
if [[ -z "$src_format" ]]
|
|
||||||
then
|
|
||||||
if [[ "$src_url" =~ ^.*\.zip$ ]] || [[ "$src_url" =~ ^.*/zipball/.*$ ]]
|
|
||||||
then
|
|
||||||
src_format="zip"
|
|
||||||
elif [[ "$src_url" =~ ^.*\.tar\.gz$ ]] || [[ "$src_url" =~ ^.*\.tgz$ ]] || [[ "$src_url" =~ ^.*/tar\.gz/.*$ ]] || [[ "$src_url" =~ ^.*/tarball/.*$ ]]
|
|
||||||
then
|
|
||||||
src_format="tar.gz"
|
|
||||||
elif [[ "$src_url" =~ ^.*\.tar\.xz$ ]]
|
|
||||||
then
|
|
||||||
src_format="tar.xz"
|
|
||||||
elif [[ "$src_url" =~ ^.*\.tar\.bz2$ ]]
|
|
||||||
then
|
|
||||||
src_format="tar.bz2"
|
|
||||||
elif [[ -z "$src_extract" ]]
|
|
||||||
then
|
|
||||||
src_extract="false"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
src_format=${src_format:-tar.gz}
|
|
||||||
src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]')
|
|
||||||
src_extract=${src_extract:-true}
|
|
||||||
|
|
||||||
if [[ "$src_extract" != "true" ]] && [[ "$src_extract" != "false" ]]
|
|
||||||
then
|
|
||||||
ynh_die "For source $source_id, expected either 'true' or 'false' for the extract parameter"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# (Unused?) mecanism where one can have the file in a special local cache to not have to download it...
|
|
||||||
local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${source_id}"
|
|
||||||
|
|
||||||
# Gotta use this trick with 'dirname' because source_id may contain slashes x_x
|
|
||||||
mkdir -p $(dirname /var/cache/yunohost/download/${YNH_APP_ID}/${source_id})
|
|
||||||
src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${source_id}"
|
|
||||||
|
|
||||||
if [ "$src_format" = "docker" ]; then
|
|
||||||
src_platform="${src_platform:-"linux/$YNH_ARCH"}"
|
|
||||||
else
|
|
||||||
if test -e "$local_src"; then
|
|
||||||
cp $local_src $src_filename
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?"
|
|
||||||
|
|
||||||
# If the file was prefetched but somehow doesn't match the sum, rm and redownload it
|
|
||||||
if [ -e "$src_filename" ] && ! echo "${src_sum} ${src_filename}" | ${src_sumprg} --check --status
|
|
||||||
then
|
|
||||||
rm -f "$src_filename"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Only redownload the file if it wasnt prefetched
|
|
||||||
if [ ! -e "$src_filename" ]
|
|
||||||
then
|
|
||||||
# NB. we have to declare the var as local first,
|
|
||||||
# otherwise 'local foo=$(false) || echo 'pwet'" does'nt work
|
|
||||||
# because local always return 0 ...
|
|
||||||
local out
|
|
||||||
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
|
||||||
out=$(wget --tries 3 --no-dns-cache --timeout 900 --no-verbose --output-document=$src_filename $src_url 2>&1) \
|
|
||||||
|| ynh_die "$out"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check the control sum
|
|
||||||
if ! echo "${src_sum} ${src_filename}" | ${src_sumprg} --check --status
|
|
||||||
then
|
|
||||||
local actual_sum="$(${src_sumprg} ${src_filename} | cut --delimiter=' ' --fields=1)"
|
|
||||||
local actual_size="$(du -hs ${src_filename} | cut --fields=1)"
|
|
||||||
rm -f ${src_filename}
|
|
||||||
ynh_die "Corrupt source for ${src_url}: Expected sha256sum to be ${src_sum} but got ${actual_sum} (size: ${actual_size})."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Keep files to be backup/restored at the end of the helper
|
|
||||||
# Assuming $dest_dir already exists
|
|
||||||
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
|
||||||
if [ -n "$keep" ] && [ -e "$dest_dir" ]; then
|
|
||||||
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
|
||||||
mkdir -p $keep_dir
|
|
||||||
local stuff_to_keep
|
|
||||||
for stuff_to_keep in $keep; do
|
|
||||||
if [ -e "$dest_dir/$stuff_to_keep" ]; then
|
|
||||||
mkdir --parents "$(dirname "$keep_dir/$stuff_to_keep")"
|
|
||||||
cp --archive "$dest_dir/$stuff_to_keep" "$keep_dir/$stuff_to_keep"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$full_replace" -eq 1 ]; then
|
|
||||||
ynh_safe_rm "$dest_dir"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract source into the app dir
|
|
||||||
mkdir --parents "$dest_dir"
|
|
||||||
|
|
||||||
if [ -n "${install_dir:-}" ] && [ "$dest_dir" == "$install_dir" ]; then
|
|
||||||
_ynh_apply_default_permissions $dest_dir
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$src_extract" == "false" ]]; then
|
|
||||||
if [[ -z "$src_rename" ]]
|
|
||||||
then
|
|
||||||
mv $src_filename $dest_dir
|
|
||||||
else
|
|
||||||
mv $src_filename $dest_dir/$src_rename
|
|
||||||
fi
|
|
||||||
elif [[ "$src_format" == "docker" ]]; then
|
|
||||||
"$YNH_HELPERS_DIR/vendor/docker-image-extract/docker-image-extract" -p $src_platform -o $dest_dir $src_url 2>&1
|
|
||||||
elif [[ "$src_format" == "zip" ]]; then
|
|
||||||
# Zip format
|
|
||||||
# Using of a temp directory, because unzip doesn't manage --strip-components
|
|
||||||
if $src_in_subdir; then
|
|
||||||
local tmp_dir=$(mktemp --directory)
|
|
||||||
unzip -quo $src_filename -d "$tmp_dir"
|
|
||||||
cp --archive $tmp_dir/*/. "$dest_dir"
|
|
||||||
ynh_safe_rm "$tmp_dir"
|
|
||||||
else
|
|
||||||
unzip -quo $src_filename -d "$dest_dir"
|
|
||||||
fi
|
|
||||||
ynh_safe_rm "$src_filename"
|
|
||||||
else
|
|
||||||
local strip=""
|
|
||||||
if [ "$src_in_subdir" != "false" ]; then
|
|
||||||
if [ "$src_in_subdir" == "true" ]; then
|
|
||||||
local sub_dirs=1
|
|
||||||
else
|
|
||||||
local sub_dirs="$src_in_subdir"
|
|
||||||
fi
|
|
||||||
strip="--strip-components $sub_dirs"
|
|
||||||
fi
|
|
||||||
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]]; then
|
|
||||||
tar --extract --file=$src_filename --directory="$dest_dir" $strip
|
|
||||||
else
|
|
||||||
ynh_die "Archive format unrecognized."
|
|
||||||
fi
|
|
||||||
ynh_safe_rm "$src_filename"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Apply patches
|
|
||||||
if [ -d "$YNH_APP_BASEDIR/patches/" ]; then
|
|
||||||
local patches_folder=$(realpath $YNH_APP_BASEDIR/patches/)
|
|
||||||
# Check if any file matching the pattern exists, cf https://stackoverflow.com/a/34195247
|
|
||||||
if compgen -G "$patches_folder/${source_id}-*.patch" >/dev/null; then
|
|
||||||
pushd "$dest_dir"
|
|
||||||
for p in $patches_folder/${source_id}-*.patch; do
|
|
||||||
echo $p
|
|
||||||
patch --strip=1 <$p || ynh_print_warn "Packagers /!\\ patch $p failed to apply"
|
|
||||||
done
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Keep files to be backup/restored at the end of the helper
|
|
||||||
# Assuming $dest_dir already exists
|
|
||||||
if [ -n "$keep" ]; then
|
|
||||||
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
|
||||||
local stuff_to_keep
|
|
||||||
for stuff_to_keep in $keep; do
|
|
||||||
if [ -e "$keep_dir/$stuff_to_keep" ]; then
|
|
||||||
mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")"
|
|
||||||
|
|
||||||
# We add "--no-target-directory" (short option is -T) to handle the special case
|
|
||||||
# when we "keep" a folder, but then the new setup already contains the same dir (but possibly empty)
|
|
||||||
# in which case a regular "cp" will create a copy of the directory inside the directory ...
|
|
||||||
# resulting in something like /var/www/$app/data/data instead of /var/www/$app/data
|
|
||||||
# cf https://unix.stackexchange.com/q/94831 for a more elaborate explanation on the option
|
|
||||||
cp --archive --no-target-directory "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 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)
|
||||||
|
@ -355,8 +72,6 @@ ynh_setup_source() {
|
||||||
# For multiple calls, cookies are persisted between each call for the same app
|
# For multiple calls, cookies are persisted between each call for the same app
|
||||||
#
|
#
|
||||||
# `$domain` and `$path` should be defined externally (and correspond to the domain.tld and the /path (of the app?))
|
# `$domain` and `$path` should be defined externally (and correspond to the domain.tld and the /path (of the app?))
|
||||||
#
|
|
||||||
# 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
|
||||||
local local_page=$(ynh_normalize_url_path $1)
|
local local_page=$(ynh_normalize_url_path $1)
|
||||||
|
@ -407,8 +122,7 @@ _acceptable_path_to_delete() {
|
||||||
local forbidden_paths=$(ls -d / /* /{var,home,usr}/* /etc/{default,sudoers.d,yunohost,cron*} /etc/yunohost/{apps,domains,hooks.d} /opt/yunohost 2> /dev/null)
|
local forbidden_paths=$(ls -d / /* /{var,home,usr}/* /etc/{default,sudoers.d,yunohost,cron*} /etc/yunohost/{apps,domains,hooks.d} /opt/yunohost 2> /dev/null)
|
||||||
|
|
||||||
# Legacy : A couple apps still have data in /home/$app ...
|
# Legacy : A couple apps still have data in /home/$app ...
|
||||||
if [[ -n "${app:-}" ]]
|
if [[ -n "${app:-}" ]]; then
|
||||||
then
|
|
||||||
forbidden_paths=$(echo "$forbidden_paths" | grep -v "/home/$app")
|
forbidden_paths=$(echo "$forbidden_paths" | grep -v "/home/$app")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -425,8 +139,6 @@ _acceptable_path_to_delete() {
|
||||||
# Remove a file or a directory, checking beforehand that it's not a disastrous location to rm such as entire /var or /home
|
# Remove a file or a directory, checking beforehand that it's not a disastrous location to rm such as entire /var or /home
|
||||||
#
|
#
|
||||||
# usage: ynh_safe_rm path_to_remove
|
# usage: ynh_safe_rm path_to_remove
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_safe_rm() {
|
ynh_safe_rm() {
|
||||||
local target="$1"
|
local target="$1"
|
||||||
set +o xtrace # set +x
|
set +o xtrace # set +x
|
||||||
|
@ -437,7 +149,7 @@ ynh_safe_rm() {
|
||||||
|
|
||||||
if [[ -z "$target" ]]; then
|
if [[ -z "$target" ]]; then
|
||||||
ynh_print_warn "ynh_safe_rm called with empty argument, ignoring."
|
ynh_print_warn "ynh_safe_rm called with empty argument, ignoring."
|
||||||
elif [[ ! -e $target ]]; then
|
elif [[ ! -e "$target" ]] && [[ ! -L "$target" ]]; then
|
||||||
ynh_print_info "'$target' wasn't deleted because it doesn't exist."
|
ynh_print_info "'$target' wasn't deleted because it doesn't exist."
|
||||||
elif ! _acceptable_path_to_delete "$target"; then
|
elif ! _acceptable_path_to_delete "$target"; then
|
||||||
ynh_print_warn "Not deleting '$target' because it is not an acceptable path to delete."
|
ynh_print_warn "Not deleting '$target' because it is not an acceptable path to delete."
|
||||||
|
@ -453,8 +165,6 @@ ynh_safe_rm() {
|
||||||
# usage: ynh_read_manifest "key"
|
# usage: ynh_read_manifest "key"
|
||||||
# | arg: key - Name of the key to find
|
# | arg: key - Name of the key to find
|
||||||
# | ret: the value associate to that key
|
# | ret: the value associate to that key
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
|
||||||
ynh_read_manifest() {
|
ynh_read_manifest() {
|
||||||
cat $YNH_APP_BASEDIR/manifest.toml | toml_to_json | jq ".$1" --raw-output
|
cat $YNH_APP_BASEDIR/manifest.toml | toml_to_json | jq ".$1" --raw-output
|
||||||
}
|
}
|
||||||
|
@ -465,10 +175,8 @@ ynh_read_manifest() {
|
||||||
# | ret: the version number of the upstream app
|
# | ret: the version number of the upstream app
|
||||||
#
|
#
|
||||||
# For example, if the manifest contains `4.3-2~ynh3` the function will return `4.3-2`
|
# For example, if the manifest contains `4.3-2~ynh3` the function will return `4.3-2`
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
|
||||||
ynh_app_upstream_version() {
|
ynh_app_upstream_version() {
|
||||||
echo "${$YNH_APP_MANIFEST_VERSION/~ynh*/}"
|
echo "${YNH_APP_MANIFEST_VERSION/~ynh*/}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return 0 if the "upstream" part of the version changed, or 1 otherwise (ie only the ~ynh suffix changed)
|
# Return 0 if the "upstream" part of the version changed, or 1 otherwise (ie only the ~ynh suffix changed)
|
||||||
|
@ -482,8 +190,6 @@ ynh_app_upstream_version_changed() {
|
||||||
# Compare the current package version is strictly lower than another version given as an argument
|
# Compare the current package version is strictly lower than another version given as an argument
|
||||||
#
|
#
|
||||||
# example: if ynh_app_upgrading_from_version_before 2.3.2~ynh1; then ...
|
# example: if ynh_app_upgrading_from_version_before 2.3.2~ynh1; then ...
|
||||||
#
|
|
||||||
# Requires YunoHost version 11.2 or higher.
|
|
||||||
ynh_app_upgrading_from_version_before() {
|
ynh_app_upgrading_from_version_before() {
|
||||||
local version=$1
|
local version=$1
|
||||||
[[ $version =~ '~ynh' ]] || ynh_die "Invalid argument for version, should include the ~ynhX prefix"
|
[[ $version =~ '~ynh' ]] || ynh_die "Invalid argument for version, should include the ~ynhX prefix"
|
||||||
|
@ -494,8 +200,6 @@ ynh_app_upgrading_from_version_before() {
|
||||||
# Compare the current package version is lower or equal to another version given as an argument
|
# Compare the current package version is lower or equal to another version given as an argument
|
||||||
#
|
#
|
||||||
# example: if ynh_app_upgrading_from_version_before_or_equal_to 2.3.2~ynh1; then ...
|
# example: if ynh_app_upgrading_from_version_before_or_equal_to 2.3.2~ynh1; then ...
|
||||||
#
|
|
||||||
# Requires YunoHost version 11.2 or higher.
|
|
||||||
ynh_app_upgrading_from_version_before_or_equal_to() {
|
ynh_app_upgrading_from_version_before_or_equal_to() {
|
||||||
local version=$1
|
local version=$1
|
||||||
[[ $version =~ '~ynh' ]] || ynh_die "Invalid argument for version, should include the ~ynhX prefix"
|
[[ $version =~ '~ynh' ]] || ynh_die "Invalid argument for version, should include the ~ynhX prefix"
|
||||||
|
@ -503,41 +207,57 @@ ynh_app_upgrading_from_version_before_or_equal_to() {
|
||||||
dpkg --compare-versions $YNH_APP_CURRENT_VERSION le $version
|
dpkg --compare-versions $YNH_APP_CURRENT_VERSION le $version
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if we should enforce sane default permissions (= disable rwx for 'others')
|
# Apply sane permissions for files installed by ynh_setup_source and ynh_config_add.
|
||||||
# on file/folders handled with ynh_setup_source and ynh_config_add
|
|
||||||
#
|
#
|
||||||
# [internal]
|
# [internal]
|
||||||
#
|
#
|
||||||
# Having a file others-readable or a folder others-executable(=enterable)
|
# * Anything below $install_dir is chown $app:$app and chmod o-rwx,g-w
|
||||||
# is a security risk comparable to "chmod 777"
|
# * The rest is considered as system configuration and chown root, chmod 400
|
||||||
#
|
|
||||||
# Configuration files may contain secrets. Or even just being able to enter a
|
|
||||||
# folder may allow an attacker to do nasty stuff (maybe a file or subfolder has
|
|
||||||
# some write permission enabled for 'other' and the attacker may edit the
|
|
||||||
# content or create files as leverage for priviledge escalation ...)
|
|
||||||
#
|
|
||||||
# The sane default should be to set ownership to $app:$app.
|
|
||||||
# In specific case, you may want to set the ownership to $app:www-data
|
|
||||||
# for example if nginx needs access to static files.
|
|
||||||
#
|
#
|
||||||
_ynh_apply_default_permissions() {
|
_ynh_apply_default_permissions() {
|
||||||
local target=$1
|
local target=$1
|
||||||
|
|
||||||
chmod o-rwx $target
|
is_in_dir() {
|
||||||
chmod g-w $target
|
# Returns false if parent is empty
|
||||||
chown -R root:root $target
|
[ -n "$2" ] || return 1
|
||||||
if ynh_system_user_exists --username=$app; then
|
local child=$(realpath "$1" 2> /dev/null)
|
||||||
chown $app:$app $target
|
local parent=$(realpath "$2" 2> /dev/null)
|
||||||
|
[[ "${child}" =~ ^$parent ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# App files can have files of their own
|
||||||
|
if ynh_system_user_exists --username="$app"; then
|
||||||
|
# If this is a file in $install_dir or $data_dir : it should be owned and read+writable by $app only
|
||||||
|
if [ -f "$target" ] && (is_in_dir "$target" "${install_dir:-}" || is_in_dir "$target" "${data_dir:-}" || is_in_dir "$target" "/etc/$app"); then
|
||||||
|
chmod 600 "$target"
|
||||||
|
chown "$app:$app" "$target"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
# If this is the install dir (so far this is the only way this helper is called with a directory)
|
||||||
|
if [ "$target" == "${install_dir:-}" ]; then
|
||||||
|
# Read the group from the install_dir manifest resource
|
||||||
|
local group="$(ynh_read_manifest 'resources.install_dir.group' | sed 's/null//g' | sed "s/__APP__/$app/g" | cut -f1 -d:)"
|
||||||
|
if [[ -z "$group" ]]; then
|
||||||
|
# We set the group to www-data for webapps that do serve static assets, which therefore need to be readable by nginx ...
|
||||||
|
# The fact that the app needs this is infered by the existence of an nginx.conf and the presence of "alias" or "root" directive
|
||||||
|
if grep -q '^\s*alias\s\|^\s*root\s' "$YNH_APP_BASEDIR/conf/nginx.conf" 2> /dev/null; then
|
||||||
|
group="www-data"
|
||||||
|
# Or default to "$app"
|
||||||
|
else
|
||||||
|
group="$app"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Files inside should be owned by $app with rw-r----- (+x for folders or files that already have +x)
|
||||||
|
# The group needs read/dirtraversal (in particular if it's www-data)
|
||||||
|
chmod -R u=rwX,g=rX,o=--- "$target"
|
||||||
|
chown -R "$app:$group" "$target"
|
||||||
|
return
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Crons should be owned by root
|
# Other files are considered system
|
||||||
# Also we don't want systemd conf, nginx conf or others stuff to be owned by the app,
|
chmod 400 "$target"
|
||||||
# otherwise they could self-edit their own systemd conf and escalate privilege
|
chown root:root "$target"
|
||||||
if echo "$target" | grep -q '^/etc/cron\|/etc/php\|/etc/nginx/conf.d\|/etc/fail2ban\|/etc/systemd/system'
|
|
||||||
then
|
|
||||||
chmod 400 $target
|
|
||||||
chown root:root $target
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int_to_bool() {
|
int_to_bool() {
|
||||||
|
@ -554,8 +274,6 @@ toml_to_json() {
|
||||||
# | ret: 0 for valid ip addresses, 1 otherwise
|
# | ret: 0 for valid ip addresses, 1 otherwise
|
||||||
#
|
#
|
||||||
# example: ynh_validate_ip 4 111.222.333.444
|
# example: ynh_validate_ip 4 111.222.333.444
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_validate_ip() {
|
ynh_validate_ip() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([f]=family= [i]=ip_address=)
|
local -A args_array=([f]=family= [i]=ip_address=)
|
||||||
|
@ -584,11 +302,9 @@ EOF
|
||||||
# [packagingv1]
|
# [packagingv1]
|
||||||
#
|
#
|
||||||
# usage: ynh_get_ram [--free|--total]
|
# usage: ynh_get_ram [--free|--total]
|
||||||
# | arg: -f, --free - Count free RAM+swap
|
# | arg: --free - Count free RAM+swap
|
||||||
# | arg: -t, --total - Count total RAM+swap
|
# | arg: --total - Count total RAM+swap
|
||||||
# | ret: the amount of free ram, in MB (MegaBytes)
|
# | ret: the amount of free ram, in MB (MegaBytes)
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.8.1 or higher.
|
|
||||||
ynh_get_ram() {
|
ynh_get_ram() {
|
||||||
# ============ Argument parsing =============
|
# ============ Argument parsing =============
|
||||||
local -A args_array=([f]=free [t]=total)
|
local -A args_array=([f]=free [t]=total)
|
||||||
|
@ -622,8 +338,246 @@ ynh_get_ram() {
|
||||||
# usage: ynh_in_ci_tests
|
# usage: ynh_in_ci_tests
|
||||||
#
|
#
|
||||||
# Return 0 if in CI, 1 otherwise
|
# Return 0 if in CI, 1 otherwise
|
||||||
#
|
|
||||||
# Requires YunoHost version 11.3 or higher.
|
|
||||||
ynh_in_ci_tests() {
|
ynh_in_ci_tests() {
|
||||||
[ "${PACKAGE_CHECK_EXEC:-0}" -eq 1 ]
|
[ "${PACKAGE_CHECK_EXEC:-0}" -eq 1 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Retrieve a YunoHost user information
|
||||||
|
#
|
||||||
|
# usage: ynh_user_get_info --username=username --key=key
|
||||||
|
# | arg: --username= - the username to retrieve info from
|
||||||
|
# | arg: --key= - the key to retrieve
|
||||||
|
# | ret: the value associate to that key
|
||||||
|
#
|
||||||
|
# example: mail=$(ynh_user_get_info --username="toto" --key=mail)
|
||||||
|
ynh_user_get_info() {
|
||||||
|
# ============ Argument parsing =============
|
||||||
|
local -A args_array=([u]=username= [k]=key=)
|
||||||
|
local username
|
||||||
|
local key
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
# ===========================================
|
||||||
|
|
||||||
|
yunohost user info "$username" --output-as json --quiet | jq -r ".$key"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the list of YunoHost users
|
||||||
|
#
|
||||||
|
# usage: ynh_user_list
|
||||||
|
# | ret: one username per line as strings
|
||||||
|
#
|
||||||
|
# example: for u in $(ynh_user_list); do ... ; done
|
||||||
|
ynh_user_list() {
|
||||||
|
yunohost user list --output-as json --quiet | jq -r ".users | keys[]"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Spawn a Bash shell with the app environment loaded
|
||||||
|
#
|
||||||
|
# usage: ynh_spawn_app_shell "appname"
|
||||||
|
#
|
||||||
|
# examples:
|
||||||
|
# ynh_spawn_app_shell "foobar" <<< 'echo "$USER"'
|
||||||
|
# ynh_spawn_app_shell "foobar" < /tmp/some_script.bash
|
||||||
|
#
|
||||||
|
# The spawned shell will have environment variables loaded and environment files sourced
|
||||||
|
# from the app's service configuration file (defaults to $app.service, overridable by the packager with `service` setting).
|
||||||
|
# If the app relies on a specific PHP version, then `php` will be aliased that version. The PHP command will also be appended with the `phpflags` settings.
|
||||||
|
ynh_spawn_app_shell() {
|
||||||
|
local app=$1
|
||||||
|
|
||||||
|
# Force Bash to be used to run this helper
|
||||||
|
[[ $0 =~ \/?bash$ ]] || ynh_die "Please use Bash as shell"
|
||||||
|
|
||||||
|
# Make sure the app is installed
|
||||||
|
test -d /etc/yunohost/apps/$app || ynh_die "$app is not an installed app ?!"
|
||||||
|
|
||||||
|
# Make sure the app has its own user
|
||||||
|
id -u "$app" &> /dev/null || ynh_die "There is no \"$app\" system user"
|
||||||
|
|
||||||
|
# Make sure the app has an install_dir setting
|
||||||
|
local install_dir=$(ynh_app_setting_get --app=$app --key=install_dir)
|
||||||
|
[ -n "$install_dir" ] || ynh_die "$app has no install_dir setting (does it use packaging format >=2?)"
|
||||||
|
|
||||||
|
# Load the app's service name, or default to $app
|
||||||
|
local service=$(ynh_app_setting_get --app=$app --key=service)
|
||||||
|
[ -z "$service" ] && service=$app
|
||||||
|
|
||||||
|
# Export HOME variable
|
||||||
|
export HOME=$install_dir
|
||||||
|
|
||||||
|
# Load the Environment variables from the app's service
|
||||||
|
local env_var=$(systemctl show $service.service -p "Environment" --value)
|
||||||
|
[ -n "$env_var" ] && export $env_var
|
||||||
|
|
||||||
|
# Force `php` to its intended version
|
||||||
|
# We use `eval`+`export` since `alias` is not propagated to subshells, even with `export`
|
||||||
|
local phpversion=$(ynh_app_setting_get --app=$app --key=phpversion)
|
||||||
|
local phpflags=$(ynh_app_setting_get --app=$app --key=phpflags)
|
||||||
|
if [ -n "$phpversion" ]; then
|
||||||
|
eval "php() { php${phpversion} ${phpflags} \"\$@\"; }"
|
||||||
|
export -f php
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Source the EnvironmentFiles from the app's service
|
||||||
|
local env_files=($(systemctl show $service.service -p "EnvironmentFiles" --value))
|
||||||
|
if [ ${#env_files[*]} -gt 0 ]; then
|
||||||
|
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
|
||||||
|
set -a
|
||||||
|
for file in ${env_files[*]}; do
|
||||||
|
[[ $file = /* ]] && source $file
|
||||||
|
done
|
||||||
|
set +a
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Activate the Python environment, if it exists
|
||||||
|
if [ -f $install_dir/venv/bin/activate ]; then
|
||||||
|
# set -/+a enables and disables new variables being automatically exported. Needed when using `source`.
|
||||||
|
set -a
|
||||||
|
source $install_dir/venv/bin/activate
|
||||||
|
set +a
|
||||||
|
fi
|
||||||
|
|
||||||
|
# cd into the WorkingDirectory set in the service, or default to the install_dir
|
||||||
|
local env_dir=$(systemctl show $service.service -p "WorkingDirectory" --value)
|
||||||
|
[ -z $env_dir ] && env_dir=$install_dir
|
||||||
|
cd $env_dir
|
||||||
|
|
||||||
|
# Spawn the app shell
|
||||||
|
su -s /bin/bash $app
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add swap
|
||||||
|
#
|
||||||
|
# usage: ynh_add_swap --size=SWAP in Mb
|
||||||
|
# | arg: -s, --size= - Amount of SWAP to add in Mb.
|
||||||
|
ynh_add_swap() {
|
||||||
|
if systemd-detect-virt --container --quiet; then
|
||||||
|
ynh_print_warn --message="You are inside a container/VM. swap will not be added, but that can cause troubles for the app $app. Please make sure you have enough RAM available."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
declare -Ar args_array=([s]=size=)
|
||||||
|
local size
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
local swap_max_size=$(($size * 1024))
|
||||||
|
|
||||||
|
local free_space=$(df --output=avail / | sed 1d)
|
||||||
|
# Because we don't want to fill the disk with a swap file, divide by 2 the available space.
|
||||||
|
local usable_space=$(($free_space / 2))
|
||||||
|
|
||||||
|
SD_CARD_CAN_SWAP=${SD_CARD_CAN_SWAP:-0}
|
||||||
|
|
||||||
|
# Swap on SD card only if it's is specified
|
||||||
|
if ynh_is_main_device_a_sd_card && [ "$SD_CARD_CAN_SWAP" == "0" ]; then
|
||||||
|
ynh_print_warn --message="The main mountpoint of your system '/' is on an SD card, swap will not be added to prevent some damage of this one, but that can cause troubles for the app $app. If you still want activate the swap, you can relaunch the command preceded by 'SD_CARD_CAN_SWAP=1'"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Compare the available space with the size of the swap.
|
||||||
|
# And set a acceptable size from the request
|
||||||
|
if [ $usable_space -ge $swap_max_size ]; then
|
||||||
|
local swap_size=$swap_max_size
|
||||||
|
elif [ $usable_space -ge $(($swap_max_size / 2)) ]; then
|
||||||
|
local swap_size=$(($swap_max_size / 2))
|
||||||
|
elif [ $usable_space -ge $(($swap_max_size / 3)) ]; then
|
||||||
|
local swap_size=$(($swap_max_size / 3))
|
||||||
|
elif [ $usable_space -ge $(($swap_max_size / 4)) ]; then
|
||||||
|
local swap_size=$(($swap_max_size / 4))
|
||||||
|
else
|
||||||
|
echo "Not enough space left for a swap file" >&2
|
||||||
|
local swap_size=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If there's enough space for a swap, and no existing swap here
|
||||||
|
if [ $swap_size -ne 0 ] && [ ! -e /swap_$app ]; then
|
||||||
|
# Create file
|
||||||
|
truncate -s 0 /swap_$app
|
||||||
|
|
||||||
|
# set the No_COW attribute on the swapfile with chattr
|
||||||
|
chattr +C /swap_$app
|
||||||
|
|
||||||
|
# Preallocate space for the swap file, fallocate may sometime not be used, use dd instead in this case
|
||||||
|
if ! fallocate -l ${swap_size}K /swap_$app; then
|
||||||
|
dd if=/dev/zero of=/swap_$app bs=1024 count=${swap_size}
|
||||||
|
fi
|
||||||
|
chmod 0600 /swap_$app
|
||||||
|
# Create the swap
|
||||||
|
mkswap /swap_$app
|
||||||
|
# And activate it
|
||||||
|
swapon /swap_$app
|
||||||
|
# Then add an entry in fstab to load this swap at each boot.
|
||||||
|
echo -e "/swap_$app swap swap defaults 0 0 #Swap added by $app" >> /etc/fstab
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ynh_del_swap() {
|
||||||
|
# If there a swap at this place
|
||||||
|
if [ -e /swap_$app ]; then
|
||||||
|
# Clean the fstab
|
||||||
|
sed -i "/#Swap added by $app/d" /etc/fstab
|
||||||
|
# Desactive the swap file
|
||||||
|
swapoff /swap_$app
|
||||||
|
# And remove it
|
||||||
|
rm /swap_$app
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the device of the main mountpoint "/" is an SD card
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# return 0 if it's an SD card, else 1
|
||||||
|
ynh_is_main_device_a_sd_card() {
|
||||||
|
if [ "$(systemd-detect-virt)" != "none" ]; then
|
||||||
|
# Assume virtualization does not take place on SD card
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local main_device=$(lsblk --output PKNAME --noheadings $(findmnt / --nofsroot --uniq --output source --noheadings --first-only))
|
||||||
|
|
||||||
|
if echo $main_device | grep --quiet "mmc" && [ $(tail -n1 /sys/block/$main_device/queue/rotational) == "0" ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check available space before creating a temp directory.
|
||||||
|
#
|
||||||
|
# usage: ynh_smart_mktemp --min_size="Min size"
|
||||||
|
#
|
||||||
|
# | arg: -s, --min_size= - Minimal size needed for the temporary directory, in Mb
|
||||||
|
ynh_smart_mktemp() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
declare -Ar args_array=([s]=min_size=)
|
||||||
|
local min_size
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
min_size="${min_size:-300}"
|
||||||
|
# Transform the minimum size from megabytes to kilobytes
|
||||||
|
min_size=$(($min_size * 1024))
|
||||||
|
|
||||||
|
# Check if there's enough free space in a directory
|
||||||
|
is_there_enough_space() {
|
||||||
|
local free_space=$(df --output=avail "$1" | sed 1d)
|
||||||
|
test $free_space -ge $min_size
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_there_enough_space /tmp; then
|
||||||
|
local tmpdir=/tmp
|
||||||
|
elif is_there_enough_space /var; then
|
||||||
|
local tmpdir=/var
|
||||||
|
elif is_there_enough_space /; then
|
||||||
|
local tmpdir=/
|
||||||
|
elif is_there_enough_space /home; then
|
||||||
|
local tmpdir=/home
|
||||||
|
else
|
||||||
|
ynh_die "Insufficient free space to continue..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$(mktemp --directory --tmpdir="$tmpdir")"
|
||||||
|
}
|
||||||
|
|
|
@ -64,14 +64,17 @@ do_init_regen() {
|
||||||
|
|
||||||
systemctl enable yunohost-api.service --quiet
|
systemctl enable yunohost-api.service --quiet
|
||||||
systemctl start yunohost-api.service
|
systemctl start yunohost-api.service
|
||||||
|
|
||||||
|
# Enable yunoprompt (in particular for installs from ISO where we want this to show on first boot instead of asking for a login/password)
|
||||||
|
systemctl enable yunoprompt --quiet
|
||||||
|
|
||||||
# Yunohost-firewall is enabled only during postinstall, not init, not 100% sure why
|
# Yunohost-firewall is enabled only during postinstall, not init, not 100% sure why
|
||||||
|
|
||||||
cp dpkg-origins /etc/dpkg/origins/yunohost
|
cp dpkg-origins /etc/dpkg/origins/yunohost
|
||||||
|
|
||||||
# Change dpkg vendor
|
# Change dpkg vendor
|
||||||
# see https://wiki.debian.org/Derivatives/Guidelines#Vendor
|
# see https://wiki.debian.org/Derivatives/Guidelines#Vendor
|
||||||
if readlink -f /etc/dpkg/origins/default | grep -q debian;
|
if readlink -f /etc/dpkg/origins/default | grep -q debian; then
|
||||||
then
|
|
||||||
rm -f /etc/dpkg/origins/default
|
rm -f /etc/dpkg/origins/default
|
||||||
ln -s /etc/dpkg/origins/yunohost /etc/dpkg/origins/default
|
ln -s /etc/dpkg/origins/yunohost /etc/dpkg/origins/default
|
||||||
fi
|
fi
|
||||||
|
@ -125,8 +128,7 @@ EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Skip ntp if inside a container (inspired from the conf of systemd-timesyncd)
|
# Skip ntp if inside a container (inspired from the conf of systemd-timesyncd)
|
||||||
if systemctl | grep -q 'ntp.service'
|
if systemctl | grep -q 'ntp.service'; then
|
||||||
then
|
|
||||||
mkdir -p ${pending_dir}/etc/systemd/system/ntp.service.d/
|
mkdir -p ${pending_dir}/etc/systemd/system/ntp.service.d/
|
||||||
cat > ${pending_dir}/etc/systemd/system/ntp.service.d/ynh-override.conf << EOF
|
cat > ${pending_dir}/etc/systemd/system/ntp.service.d/ynh-override.conf << EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
|
@ -188,8 +190,7 @@ do_post_regen() {
|
||||||
find /etc/systemd/system/*.service -type f | xargs -r chown root:root
|
find /etc/systemd/system/*.service -type f | xargs -r chown root:root
|
||||||
find /etc/systemd/system/*.service -type f | xargs -r chmod 0644
|
find /etc/systemd/system/*.service -type f | xargs -r chmod 0644
|
||||||
|
|
||||||
if ls -l /etc/php/*/fpm/pool.d/*.conf
|
if ls -l /etc/php/*/fpm/pool.d/*.conf; then
|
||||||
then
|
|
||||||
chown root:root /etc/php/*/fpm/pool.d/*.conf
|
chown root:root /etc/php/*/fpm/pool.d/*.conf
|
||||||
chmod 644 /etc/php/*/fpm/pool.d/*.conf
|
chmod 644 /etc/php/*/fpm/pool.d/*.conf
|
||||||
fi
|
fi
|
||||||
|
@ -231,8 +232,7 @@ do_post_regen() {
|
||||||
grep -q '^sftp.app:' /etc/group || groupadd sftp.app
|
grep -q '^sftp.app:' /etc/group || groupadd sftp.app
|
||||||
|
|
||||||
# Propagates changes in systemd service config overrides
|
# Propagates changes in systemd service config overrides
|
||||||
if systemctl | grep -q 'ntp.service'
|
if systemctl | grep -q 'ntp.service'; then
|
||||||
then
|
|
||||||
[[ ! "$regen_conf_files" =~ "ntp.service.d/ynh-override.conf" ]] || {
|
[[ ! "$regen_conf_files" =~ "ntp.service.d/ynh-override.conf" ]] || {
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl restart ntp
|
systemctl restart ntp
|
||||||
|
@ -259,14 +259,12 @@ do_post_regen() {
|
||||||
|
|
||||||
# Change dpkg vendor
|
# Change dpkg vendor
|
||||||
# see https://wiki.debian.org/Derivatives/Guidelines#Vendor
|
# see https://wiki.debian.org/Derivatives/Guidelines#Vendor
|
||||||
if readlink -f /etc/dpkg/origins/default | grep -q debian;
|
if readlink -f /etc/dpkg/origins/default | grep -q debian; then
|
||||||
then
|
|
||||||
rm -f /etc/dpkg/origins/default
|
rm -f /etc/dpkg/origins/default
|
||||||
ln -s /etc/dpkg/origins/yunohost /etc/dpkg/origins/default
|
ln -s /etc/dpkg/origins/yunohost /etc/dpkg/origins/default
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -e /etc/yunohost/installed && test -e /etc/profile.d/check_yunohost_is_installed.sh
|
if test -e /etc/yunohost/installed && test -e /etc/profile.d/check_yunohost_is_installed.sh; then
|
||||||
then
|
|
||||||
rm /etc/profile.d/check_yunohost_is_installed.sh
|
rm /etc/profile.d/check_yunohost_is_installed.sh
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
ssl_dir="/usr/share/yunohost/ssl"
|
ssl_dir="/usr/share/yunohost/ssl"
|
||||||
template_dir="/usr/share/yunohost/conf/ssl/"
|
template_dir="/usr/share/yunohost/conf/ssl"
|
||||||
ynh_ca="/etc/yunohost/certs/yunohost.org/ca.pem"
|
ynh_ca="/etc/yunohost/certs/yunohost.org/ca.pem"
|
||||||
ynh_crt="/etc/yunohost/certs/yunohost.org/crt.pem"
|
ynh_crt="/etc/yunohost/certs/yunohost.org/crt.pem"
|
||||||
ynh_key="/etc/yunohost/certs/yunohost.org/key.pem"
|
ynh_key="/etc/yunohost/certs/yunohost.org/key.pem"
|
||||||
|
@ -106,8 +106,7 @@ do_post_regen() {
|
||||||
main_domain=$(cat /etc/yunohost/current_host)
|
main_domain=$(cat /etc/yunohost/current_host)
|
||||||
|
|
||||||
# Automigrate legacy folder
|
# Automigrate legacy folder
|
||||||
if [ -e /usr/share/yunohost/yunohost-config/ssl/yunoCA ]
|
if [ -e /usr/share/yunohost/yunohost-config/ssl/yunoCA ]; then
|
||||||
then
|
|
||||||
mv /usr/share/yunohost/yunohost-config/ssl/yunoCA/* ${ssl_dir}
|
mv /usr/share/yunohost/yunohost-config/ssl/yunoCA/* ${ssl_dir}
|
||||||
rm -rf /usr/share/yunohost/yunohost-config
|
rm -rf /usr/share/yunohost/yunohost-config
|
||||||
# Overwrite openssl.cnf because it may still contain references to the old yunoCA dir
|
# Overwrite openssl.cnf because it may still contain references to the old yunoCA dir
|
||||||
|
|
|
@ -56,7 +56,6 @@ Pin: release *
|
||||||
Pin-Priority: -1
|
Pin-Priority: -1
|
||||||
" >> "${pending_dir}/etc/apt/preferences.d/ban_packages"
|
" >> "${pending_dir}/etc/apt/preferences.d/ban_packages"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do_post_regen() {
|
do_post_regen() {
|
||||||
|
@ -68,14 +67,12 @@ do_post_regen() {
|
||||||
|
|
||||||
# Add sury key
|
# Add sury key
|
||||||
# We do this only at the post regen and if the key doesn't already exists, because we don't want the regenconf to fuck everything up if the regenconf runs while the network is down
|
# We do this only at the post regen and if the key doesn't already exists, because we don't want the regenconf to fuck everything up if the regenconf runs while the network is down
|
||||||
if [[ ! -s /etc/apt/trusted.gpg.d/extra_php_version.gpg ]]
|
if [[ ! -s /etc/apt/trusted.gpg.d/extra_php_version.gpg ]]; then
|
||||||
then
|
|
||||||
wget --timeout 900 --quiet "https://packages.sury.org/php/apt.gpg" --output-document=- | gpg --dearmor > "/etc/apt/trusted.gpg.d/extra_php_version.gpg"
|
wget --timeout 900 --quiet "https://packages.sury.org/php/apt.gpg" --output-document=- | gpg --dearmor > "/etc/apt/trusted.gpg.d/extra_php_version.gpg"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make sure php7.4 is the default version when using php in cli
|
# Make sure php7.4 is the default version when using php in cli
|
||||||
if test -e /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
if test -e /usr/bin/php$YNH_DEFAULT_PHP_VERSION; then
|
||||||
then
|
|
||||||
update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if ! dpkg --list | grep -q 'ii *metronome '
|
if ! dpkg --list | grep -q 'ii *metronome '; then
|
||||||
then
|
|
||||||
echo 'metronome is not installed, skipping'
|
echo 'metronome is not installed, skipping'
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
@ -74,15 +73,12 @@ do_post_regen() {
|
||||||
chown -R metronome: /var/lib/metronome/
|
chown -R metronome: /var/lib/metronome/
|
||||||
chown -R metronome: /etc/metronome/conf.d/
|
chown -R metronome: /etc/metronome/conf.d/
|
||||||
|
|
||||||
if [[ -z "$(ls /etc/metronome/conf.d/*.cfg.lua 2>/dev/null)" ]]
|
if [[ -z "$(ls /etc/metronome/conf.d/*.cfg.lua 2> /dev/null)" ]]; then
|
||||||
then
|
if systemctl is-enabled metronome &> /dev/null; then
|
||||||
if systemctl is-enabled metronome &>/dev/null
|
|
||||||
then
|
|
||||||
systemctl disable metronome --now 2> /dev/null
|
systemctl disable metronome --now 2> /dev/null
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if ! systemctl is-enabled metronome &>/dev/null
|
if ! systemctl is-enabled metronome &> /dev/null; then
|
||||||
then
|
|
||||||
systemctl enable metronome --now 2> /dev/null
|
systemctl enable metronome --now 2> /dev/null
|
||||||
sleep 3
|
sleep 3
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -86,22 +86,19 @@ do_pre_regen() {
|
||||||
export domain_cert_ca=$(echo $cert_status \
|
export domain_cert_ca=$(echo $cert_status \
|
||||||
| jq ".certificates.\"$domain\".CA_type" \
|
| jq ".certificates.\"$domain\".CA_type" \
|
||||||
| tr -d '"')
|
| tr -d '"')
|
||||||
if echo "$xmpp_domain_list" | grep -q "^$domain$"
|
if echo "$xmpp_domain_list" | grep -q "^$domain$"; then
|
||||||
then
|
|
||||||
export xmpp_enabled="True"
|
export xmpp_enabled="True"
|
||||||
else
|
else
|
||||||
export xmpp_enabled="False"
|
export xmpp_enabled="False"
|
||||||
fi
|
fi
|
||||||
if echo "$mail_domain_list" | grep -q "^$domain$"
|
if echo "$mail_domain_list" | grep -q "^$domain$"; then
|
||||||
then
|
|
||||||
export mail_enabled="True"
|
export mail_enabled="True"
|
||||||
else
|
else
|
||||||
export mail_enabled="False"
|
export mail_enabled="False"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ynh_render_template "server.tpl.conf" "${nginx_conf_dir}/${domain}.conf"
|
ynh_render_template "server.tpl.conf" "${nginx_conf_dir}/${domain}.conf"
|
||||||
if [ $mail_enabled == "True" ]
|
if [ $mail_enabled == "True" ]; then
|
||||||
then
|
|
||||||
ynh_render_template "autoconfig.tpl.xml" "${mail_autoconfig_dir}/config-v1.1.xml"
|
ynh_render_template "autoconfig.tpl.xml" "${mail_autoconfig_dir}/config-v1.1.xml"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -144,8 +141,7 @@ do_pre_regen() {
|
||||||
do_post_regen() {
|
do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
if ls -l /etc/nginx/conf.d/*.d/*.conf
|
if ls -l /etc/nginx/conf.d/*.d/*.conf; then
|
||||||
then
|
|
||||||
chown root:root /etc/nginx/conf.d/*.d/*.conf
|
chown root:root /etc/nginx/conf.d/*.d/*.conf
|
||||||
chmod 644 /etc/nginx/conf.d/*.d/*.conf
|
chmod 644 /etc/nginx/conf.d/*.d/*.conf
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -45,6 +45,19 @@ do_pre_regen() {
|
||||||
|
|
||||||
cat <<< "[${relay_host}]:${relay_port} ${relay_user}:${relay_password}" > ${postfix_dir}/sasl_passwd
|
cat <<< "[${relay_host}]:${relay_port} ${relay_user}:${relay_password}" > ${postfix_dir}/sasl_passwd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Use this postfix server as a backup MX
|
||||||
|
export backup_mx_domains="$(yunohost settings get 'email.smtp.smtp_backup_mx_domains' | sed "s/,/ /g")"
|
||||||
|
export backup_mx_emails="$(yunohost settings get 'email.smtp.smtp_backup_mx_emails_whitelisted' | sed "s/,/ /g")"
|
||||||
|
rm -f ${postfix_dir}/relay_recipients
|
||||||
|
touch ${postfix_dir}/relay_recipients
|
||||||
|
if [ -n "${backup_mx_domains}" ] && [ -n "${backup_mx_emails}" ]; then
|
||||||
|
for mail in ${backup_mx_emails}; do
|
||||||
|
echo "$mail OK" >> ${postfix_dir}/relay_recipients
|
||||||
|
done
|
||||||
|
postmap ${postfix_dir}/relay_recipients
|
||||||
|
fi
|
||||||
|
|
||||||
export main_domain
|
export main_domain
|
||||||
export domain_list="$(yunohost domain list --features mail_in mail_out --output-as json | jq -r ".domains[]" | tr '\n' ' ')"
|
export domain_list="$(yunohost domain list --features mail_in mail_out --output-as json | jq -r ".domains[]" | tr '\n' ' ')"
|
||||||
ynh_render_template "main.cf" "${postfix_dir}/main.cf"
|
ynh_render_template "main.cf" "${postfix_dir}/main.cf"
|
||||||
|
@ -78,6 +91,11 @@ do_post_regen() {
|
||||||
postmap /etc/postfix/sasl_passwd
|
postmap /etc/postfix/sasl_passwd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -e /etc/postfix/relay_recipients ]; then
|
||||||
|
chmod 750 /etc/postfix/relay_recipients*
|
||||||
|
chown postfix:root /etc/postfix/relay_recipients*
|
||||||
|
fi
|
||||||
|
|
||||||
postmap -F hash:/etc/postfix/sni
|
postmap -F hash:/etc/postfix/sni
|
||||||
|
|
||||||
python3 -c 'from yunohost.app import regen_mail_app_user_config_for_dovecot_and_postfix as r; r(only="postfix")'
|
python3 -c 'from yunohost.app import regen_mail_app_user_config_for_dovecot_and_postfix as r; r(only="postfix")'
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
set -e
|
set -e
|
||||||
. /usr/share/yunohost/helpers
|
. /usr/share/yunohost/helpers
|
||||||
|
|
||||||
if ! dpkg --list | grep -q 'ii *mariadb-server '
|
if ! dpkg --list | grep -q 'ii *mariadb-server '; then
|
||||||
then
|
|
||||||
echo 'mysql/mariadb is not installed, skipping'
|
echo 'mysql/mariadb is not installed, skipping'
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -3,18 +3,15 @@
|
||||||
set -e
|
set -e
|
||||||
. /usr/share/yunohost/helpers
|
. /usr/share/yunohost/helpers
|
||||||
|
|
||||||
if ! dpkg --list | grep -q "ii *postgresql-$PSQL_VERSION "
|
if ! dpkg --list | grep -q "ii *postgresql-$PSQL_VERSION "; then
|
||||||
then
|
|
||||||
echo 'postgresql is not installed, skipping'
|
echo 'postgresql is not installed, skipping'
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -e "/etc/postgresql/$PSQL_VERSION" ]
|
if [ ! -e "/etc/postgresql/$PSQL_VERSION" ]; then
|
||||||
then
|
|
||||||
ynh_die --message="It looks like postgresql was not properly configured ? /etc/postgresql/$PSQL_VERSION is missing ... Could be due to a locale issue, c.f.https://serverfault.com/questions/426989/postgresql-etc-postgresql-doesnt-exist"
|
ynh_die --message="It looks like postgresql was not properly configured ? /etc/postgresql/$PSQL_VERSION is missing ... Could be due to a locale issue, c.f.https://serverfault.com/questions/426989/postgresql-etc-postgresql-doesnt-exist"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
do_pre_regen() {
|
do_pre_regen() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -35,7 +32,10 @@ do_post_regen() {
|
||||||
ynh_string_random > $PSQL_ROOT_PWD_FILE
|
ynh_string_random > $PSQL_ROOT_PWD_FILE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ ! -e $PSQL_ROOT_PWD_FILE ] || { chown root:postgres $PSQL_ROOT_PWD_FILE; chmod 440 $PSQL_ROOT_PWD_FILE; }
|
[ ! -e $PSQL_ROOT_PWD_FILE ] || {
|
||||||
|
chown root:postgres $PSQL_ROOT_PWD_FILE
|
||||||
|
chmod 440 $PSQL_ROOT_PWD_FILE
|
||||||
|
}
|
||||||
|
|
||||||
sudo --login --user=postgres psql -c"ALTER user postgres WITH PASSWORD '$(cat $PSQL_ROOT_PWD_FILE)'" postgres
|
sudo --login --user=postgres psql -c"ALTER user postgres WITH PASSWORD '$(cat $PSQL_ROOT_PWD_FILE)'" postgres
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,7 @@ set -e
|
||||||
_generate_config() {
|
_generate_config() {
|
||||||
echo "domains:"
|
echo "domains:"
|
||||||
# Add yunohost.local (only if yunohost.local ain't already in ynh_domains)
|
# Add yunohost.local (only if yunohost.local ain't already in ynh_domains)
|
||||||
if ! echo "$YNH_DOMAINS" | tr ' ' '\n' | grep -q --line-regexp 'yunohost.local'
|
if ! echo "$YNH_DOMAINS" | tr ' ' '\n' | grep -q --line-regexp 'yunohost.local'; then
|
||||||
then
|
|
||||||
echo " - yunohost.local"
|
echo " - yunohost.local"
|
||||||
fi
|
fi
|
||||||
for domain in $YNH_DOMAINS; do
|
for domain in $YNH_DOMAINS; do
|
||||||
|
@ -15,10 +14,8 @@ _generate_config() {
|
||||||
[[ "$domain" =~ ^[^.]+\.local$ ]] || continue
|
[[ "$domain" =~ ^[^.]+\.local$ ]] || continue
|
||||||
echo " - $domain"
|
echo " - $domain"
|
||||||
done
|
done
|
||||||
if [[ -e /etc/yunohost/mdns.aliases ]]
|
if [[ -e /etc/yunohost/mdns.aliases ]]; then
|
||||||
then
|
for localalias in $(cat /etc/yunohost/mdns.aliases | grep -v "^ *$"); do
|
||||||
for localalias in $(cat /etc/yunohost/mdns.aliases | grep -v "^ *$")
|
|
||||||
do
|
|
||||||
echo " - $localalias.local"
|
echo " - $localalias.local"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -51,8 +51,7 @@ do_pre_regen() {
|
||||||
conf_files=$(ls -1 /etc/dnsmasq.d \
|
conf_files=$(ls -1 /etc/dnsmasq.d \
|
||||||
| awk '/^[^\.]+\.[^\.]+.*$/ { print $1 }')
|
| awk '/^[^\.]+\.[^\.]+.*$/ { print $1 }')
|
||||||
for domain in $conf_files; do
|
for domain in $conf_files; do
|
||||||
if [[ ! $YNH_DOMAINS =~ $domain ]] && [[ ! $domain =~ \.local$ ]]
|
if [[ ! $YNH_DOMAINS =~ $domain ]] && [[ ! $domain =~ \.local$ ]]; then
|
||||||
then
|
|
||||||
touch "${dnsmasq_dir}/${domain}"
|
touch "${dnsmasq_dir}/${domain}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
@ -24,8 +24,7 @@ do_pre_regen() {
|
||||||
do_post_regen() {
|
do_post_regen() {
|
||||||
regen_conf_files=$1
|
regen_conf_files=$1
|
||||||
|
|
||||||
if ls -l /etc/fail2ban/jail.d/*.conf
|
if ls -l /etc/fail2ban/jail.d/*.conf; then
|
||||||
then
|
|
||||||
chown root:root /etc/fail2ban/jail.d/*.conf
|
chown root:root /etc/fail2ban/jail.d/*.conf
|
||||||
chmod 644 /etc/fail2ban/jail.d/*.conf
|
chmod 644 /etc/fail2ban/jail.d/*.conf
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
"mail_forward_remove_failed": "Die Weiterleitungs-E-Mail '{mail}' konnte nicht gelöscht werden",
|
"mail_forward_remove_failed": "Die Weiterleitungs-E-Mail '{mail}' konnte nicht gelöscht werden",
|
||||||
"main_domain_change_failed": "Die Hauptdomain konnte nicht geändert werden",
|
"main_domain_change_failed": "Die Hauptdomain konnte nicht geändert werden",
|
||||||
"main_domain_changed": "Die Hauptdomain wurde geändert",
|
"main_domain_changed": "Die Hauptdomain wurde geändert",
|
||||||
"pattern_backup_archive_name": "Muss ein gültiger Dateiname mit maximal 30 Zeichen sein, ausschliesslich alphanumerische Zeichen und -_.",
|
"pattern_backup_archive_name": "Muss ein gültiger Dateiname mit maximal 30 Zeichen sein, ausschließlich alphanumerische Zeichen und -_.",
|
||||||
"pattern_domain": "Muss ein gültiger Domainname sein (z.B. meine-domain.org)",
|
"pattern_domain": "Muss ein gültiger Domainname sein (z.B. meine-domain.org)",
|
||||||
"pattern_email": "Es muss sich um eine gültige E-Mail-Adresse handeln, ohne '+'-Symbol (z. B. name@domäne.de)",
|
"pattern_email": "Es muss sich um eine gültige E-Mail-Adresse handeln, ohne '+'-Symbol (z. B. name@domäne.de)",
|
||||||
"pattern_firstname": "Muss ein gültiger Vorname sein (mindestens 3 Zeichen)",
|
"pattern_firstname": "Muss ein gültiger Vorname sein (mindestens 3 Zeichen)",
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
{
|
{
|
||||||
"password_too_simple_1": "Ο κωδικός πρόσβασης πρέπει να έχει τουλάχιστον 8 χαρακτήρες",
|
"password_too_simple_1": "Ο κωδικός πρόσβασης πρέπει να έχει τουλάχιστον 8 χαρακτήρες",
|
||||||
"aborting": "Ματαίωση."
|
"aborting": "Ματαίωση.",
|
||||||
|
"action_invalid": "Μη έγκυρη ενέργεια '{action}'",
|
||||||
|
"app_action_broke_system": "Αυτή η ενέργεια φαίνεται να έχει προκαλέσει προβλήματα σε αυτές τις σημαντικές υπηρεσίες: {services}",
|
||||||
|
"app_already_installed": "Η φαρμογή {app} είναι ήδη εγκατεστημένη",
|
||||||
|
"admin_password": "Κωδικός διαχείρισης",
|
||||||
|
"all_users": "Όλοι οι χρήστες YunoHost",
|
||||||
|
"admins": "Διαχειριστές",
|
||||||
|
"app_action_failed": "Αποτυχία εκτέλεσης ενέργειας {action} για την εφαρμογή {app}",
|
||||||
|
"already_up_to_date": "Δεν υπάρχει τίποτα να γίνει. Όλα είναι επικαιροποιημένα."
|
||||||
}
|
}
|
|
@ -248,6 +248,13 @@
|
||||||
"diagnosis_http_special_use_tld": "Domain {domain} is based on a special-use top-level domain (TLD) such as .local or .test and is therefore not expected to be exposed outside the local network.",
|
"diagnosis_http_special_use_tld": "Domain {domain} is based on a special-use top-level domain (TLD) such as .local or .test and is therefore not expected to be exposed outside the local network.",
|
||||||
"diagnosis_http_timeout": "Timed-out while trying to contact your server from the outside. It appears to be unreachable.<br>1. The most common cause for this issue is that port 80 (and 443) <a href='https://yunohost.org/isp_box_config'>are not correctly forwarded to your server</a>.<br>2. You should also make sure that the service nginx is running<br>3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.",
|
"diagnosis_http_timeout": "Timed-out while trying to contact your server from the outside. It appears to be unreachable.<br>1. The most common cause for this issue is that port 80 (and 443) <a href='https://yunohost.org/isp_box_config'>are not correctly forwarded to your server</a>.<br>2. You should also make sure that the service nginx is running<br>3. On more complex setups: make sure that no firewall or reverse-proxy is interfering.",
|
||||||
"diagnosis_http_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network.",
|
"diagnosis_http_unreachable": "Domain {domain} appears unreachable through HTTP from outside the local network.",
|
||||||
|
"diagnosis_ignore_already_filtered": "(There is already a diagnosis {category} filter with these criterias)",
|
||||||
|
"diagnosis_ignore_criteria_error": "Criterias should be of the form key=value (e.g. domain=yolo.test)",
|
||||||
|
"diagnosis_ignore_filter_added": "Added a {category} diagnosis filter",
|
||||||
|
"diagnosis_ignore_filter_removed": "Removed a {category} diagnosis filter",
|
||||||
|
"diagnosis_ignore_missing_criteria": "You should provide at least one criteria being the diagnosis category to ignore",
|
||||||
|
"diagnosis_ignore_no_filter_found": "(There is no such diagnosis {category} filter with these criterias to remove)",
|
||||||
|
"diagnosis_ignore_no_issue_found": "No issues was found matching the given criteria.",
|
||||||
"diagnosis_ignored_issues": "(+ {nb_ignored} ignored issue(s))",
|
"diagnosis_ignored_issues": "(+ {nb_ignored} ignored issue(s))",
|
||||||
"diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason… Is a firewall blocking DNS requests?",
|
"diagnosis_ip_broken_dnsresolution": "Domain name resolution seems to be broken for some reason… Is a firewall blocking DNS requests?",
|
||||||
"diagnosis_ip_broken_resolvconf": "Domain name resolution seems to be broken on your server, which seems related to <code>/etc/resolv.conf</code> not pointing to <code>127.0.0.1</code>.",
|
"diagnosis_ip_broken_resolvconf": "Domain name resolution seems to be broken on your server, which seems related to <code>/etc/resolv.conf</code> not pointing to <code>127.0.0.1</code>.",
|
||||||
|
@ -309,6 +316,8 @@
|
||||||
"diagnosis_regenconf_allgood": "All configuration files are in line with the recommended configuration!",
|
"diagnosis_regenconf_allgood": "All configuration 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": "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_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_rfkill_wifi": "The Wi-Fi card is disabled and a system warning might prevent app installations",
|
||||||
|
"diagnosis_rfkill_wifi_details": "This warning sneaks in many command outputs, breaking some apps. It is usually required to specify your country code with the command <code>sudo raspi-config</code>. Here is the error:<br>{rfkill_wifi_error}",
|
||||||
"diagnosis_rootfstotalspace_critical": "The root filesystem only has a total of {space} which is quite worrisome! You will likely run out of disk space very quickly! It's recommended to have at least 16 GB for the root filesystem.",
|
"diagnosis_rootfstotalspace_critical": "The root filesystem only has a total of {space} which is quite worrisome! You will likely run out of disk space very quickly! It's recommended to have at least 16 GB for the root filesystem.",
|
||||||
"diagnosis_rootfstotalspace_warning": "The root filesystem only has a total of {space}. This may be okay, but be careful because ultimately you may run out of disk space quickly… It's recommended to have at least 16 GB for the root filesystem.",
|
"diagnosis_rootfstotalspace_warning": "The root filesystem only has a total of {space}. This may be okay, but be careful because ultimately you may run out of disk space quickly… It's recommended to have at least 16 GB for the root filesystem.",
|
||||||
"diagnosis_security_vulnerable_to_meltdown": "You appear vulnerable to the Meltdown critical security vulnerability",
|
"diagnosis_security_vulnerable_to_meltdown": "You appear vulnerable to the Meltdown critical security vulnerability",
|
||||||
|
@ -449,6 +458,10 @@
|
||||||
"global_settings_setting_security_experimental_enabled_help": "Enable experimental security features (don't enable this if you don't know what you're doing!)",
|
"global_settings_setting_security_experimental_enabled_help": "Enable experimental security features (don't enable this if you don't know what you're doing!)",
|
||||||
"global_settings_setting_smtp_allow_ipv6": "Allow IPv6",
|
"global_settings_setting_smtp_allow_ipv6": "Allow IPv6",
|
||||||
"global_settings_setting_smtp_allow_ipv6_help": "Allow the use of IPv6 to receive and send mail",
|
"global_settings_setting_smtp_allow_ipv6_help": "Allow the use of IPv6 to receive and send mail",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains": "Domains to act as secondary MX for",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains_help": "Allow this server to act as a backup *secondary* MX domain for the listed domain. This means that if the main MX for the domain is not reachable (for example because of an outage), mails will still be sent to this server, which will keep them during a maximum of 20 days and try to relay them to the real destination once it goes back up. Several domains can be provided, separated by commas.",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted": "SMTP backup MX emails whitelist",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted_help": "When acting as a secondary MX, the exhaustive list of allowed recipient's email addresses must be provided (otherwise mails will be refused and discarded). Several entries can be provided, separated by commas.",
|
||||||
"global_settings_setting_smtp_relay_enabled": "Enable SMTP relay",
|
"global_settings_setting_smtp_relay_enabled": "Enable SMTP relay",
|
||||||
"global_settings_setting_smtp_relay_enabled_help": "Enable the SMTP relay to use in order to send mail instead of this yunohost instance. Useful if you are in one of this situation: your 25 port is blocked by your ISP or VPS provider, you have a residential IP listed on DUHL, you are not able to configure reverse DNS or this server is not directly exposed on the internet and you want use an other one to send mails.",
|
"global_settings_setting_smtp_relay_enabled_help": "Enable the SMTP relay to use in order to send mail instead of this yunohost instance. Useful if you are in one of this situation: your 25 port is blocked by your ISP or VPS provider, you have a residential IP listed on DUHL, you are not able to configure reverse DNS or this server is not directly exposed on the internet and you want use an other one to send mails.",
|
||||||
"global_settings_setting_smtp_relay_host": "SMTP relay host",
|
"global_settings_setting_smtp_relay_host": "SMTP relay host",
|
||||||
|
@ -573,7 +586,7 @@
|
||||||
"migration_0021_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade.",
|
"migration_0021_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade.",
|
||||||
"migration_0021_main_upgrade": "Starting main upgrade…",
|
"migration_0021_main_upgrade": "Starting main upgrade…",
|
||||||
"migration_0021_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_0021_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_0021_not_buster2": "The current Debian distribution is not Buster! If you already ran the Buster->Bullseye migration, then this error is symptomatic of the fact that the migration procedure was not 100% succesful (otherwise YunoHost would have flagged it as completed). It is recommended to investigate what happened with the support team, who will need the **full** log of the `migration, which can be found in Tools > Logs in the webadmin.",
|
"migration_0021_not_buster2": "The current Debian distribution is not Buster! If you already ran the Buster -> Bullseye migration, then this error is symptomatic of the fact that the migration procedure was not 100% succesful (otherwise YunoHost would have flagged it as completed). It is recommended to investigate what happened with the support team, who will need the **full** log of the migration, which can be found in Tools > Logs in the webadmin.",
|
||||||
"migration_0021_not_enough_free_space": "Free space is pretty low in /var/! You should have at least 1GB free to run this migration.",
|
"migration_0021_not_enough_free_space": "Free space is pretty low in /var/! You should have at least 1GB free to run this migration.",
|
||||||
"migration_0021_patch_yunohost_conflicts": "Applying patch to workaround conflict issue…",
|
"migration_0021_patch_yunohost_conflicts": "Applying patch to workaround conflict issue…",
|
||||||
"migration_0021_patching_sources_list": "Patching the sources.lists…",
|
"migration_0021_patching_sources_list": "Patching the sources.lists…",
|
||||||
|
@ -591,12 +604,27 @@
|
||||||
"migration_0024_rebuild_python_venv_disclaimer_rebuild": "Rebuilding the virtualenv will be attempted for the following apps (NB: the operation may take some time!): {rebuild_apps}",
|
"migration_0024_rebuild_python_venv_disclaimer_rebuild": "Rebuilding the virtualenv will be attempted for the following apps (NB: the operation may take some time!): {rebuild_apps}",
|
||||||
"migration_0024_rebuild_python_venv_failed": "Failed to rebuild the Python virtualenv for {app}. The app may not work as long as this is not resolved. You should fix the situation by forcing the upgrade of this app using `yunohost app upgrade --force {app}`.",
|
"migration_0024_rebuild_python_venv_failed": "Failed to rebuild the Python virtualenv for {app}. The app may not work as long as this is not resolved. You should fix the situation by forcing the upgrade of this app using `yunohost app upgrade --force {app}`.",
|
||||||
"migration_0024_rebuild_python_venv_in_progress": "Now attempting to rebuild the Python virtualenv for `{app}`",
|
"migration_0024_rebuild_python_venv_in_progress": "Now attempting to rebuild the Python virtualenv for `{app}`",
|
||||||
|
"migration_0027_cleaning_up": "Cleaning up cache and packages not useful anymore…",
|
||||||
|
"migration_0027_delayed_api_restart": "The YunoHost API will automatically be restarted in 15 seconds. It may be unavailable for a few seconds, and then you will have to login again.",
|
||||||
|
"migration_0027_general_warning": "Please note that this migration is a delicate operation. The YunoHost team did its best to review and test it, but the migration might still break parts of the system or its apps.\n\nTherefore, it is recommended to:\n - Perform a backup of any critical data or app. More info on https://yunohost.org/backup;\n - Be patient after launching the migration: Depending on your Internet connection and hardware, it might take up to a few hours for everything to upgrade properly.",
|
||||||
|
"migration_0027_main_upgrade": "Starting main upgrade…",
|
||||||
|
"migration_0027_modified_files": "Please note that the following files were found to be manually modified and might be overwritten following the upgrade: {manually_modified_files}",
|
||||||
|
"migration_0027_not_bullseye": "The current Debian distribution is not Bullseye! If you already ran the Bullseye -> Bookworm migration, then this error is symptomatic of the fact that the migration procedure was not 100% succesful (otherwise YunoHost would have flagged it as completed). It is recommended to investigate what happened with the support team, who will need the **full** log of the migration, which can be found in Tools > Logs in the webadmin.",
|
||||||
|
"migration_0027_not_enough_free_space": "Free space is pretty low in /var/! You should have at least 1GB free to run this migration.",
|
||||||
|
"migration_0027_patch_yunohost_conflicts": "Applying patch to workaround conflict issue…",
|
||||||
|
"migration_0027_patching_sources_list": "Patching the sources.lists file…",
|
||||||
|
"migration_0027_problematic_apps_warning": "Please note that the following possibly problematic installed apps were detected. It looks like those were not installed from the YunoHost app catalog, or are not flagged as 'working'. Consequently, it cannot be guaranteed that they will still work after the upgrade: {problematic_apps}",
|
||||||
|
"migration_0027_start": "Starting migration to Bookworm…",
|
||||||
|
"migration_0027_still_on_bullseye_after_main_upgrade": "Something went wrong during the main upgrade, the system appears to still be on Debian Bullseye.",
|
||||||
|
"migration_0027_system_not_fully_up_to_date": "Your system is not fully up-to-date. Please perform a regular upgrade before running the migration to Bookworm.",
|
||||||
|
"migration_0027_yunohost_upgrade": "Starting YunoHost core upgrade…",
|
||||||
"migration_description_0021_migrate_to_bullseye": "Upgrade the system to Debian Bullseye and YunoHost 11.x",
|
"migration_description_0021_migrate_to_bullseye": "Upgrade the system to Debian Bullseye and YunoHost 11.x",
|
||||||
"migration_description_0022_php73_to_php74_pools": "Migrate php7.3-fpm 'pool' conf files to php7.4",
|
"migration_description_0022_php73_to_php74_pools": "Migrate php7.3-fpm 'pool' conf files to php7.4",
|
||||||
"migration_description_0023_postgresql_11_to_13": "Migrate databases from PostgreSQL 11 to 13",
|
"migration_description_0023_postgresql_11_to_13": "Migrate databases from PostgreSQL 11 to 13",
|
||||||
"migration_description_0024_rebuild_python_venv": "Repair Python app after bullseye migration",
|
"migration_description_0024_rebuild_python_venv": "Repair Python app after bullseye migration",
|
||||||
"migration_description_0025_global_settings_to_configpanel": "Migrate legacy global settings nomenclature to the new, modern nomenclature",
|
"migration_description_0025_global_settings_to_configpanel": "Migrate legacy global settings nomenclature to the new, modern nomenclature",
|
||||||
"migration_description_0026_new_admins_group": "Migrate to the new 'multiple admins' system",
|
"migration_description_0026_new_admins_group": "Migrate to the new 'multiple admins' system",
|
||||||
|
"migration_description_0027_migrate_to_bookworm": "Upgrade the system to Debian Bookworm and YunoHost 12",
|
||||||
"migration_ldap_backup_before_migration": "Creating a backup of LDAP database and apps settings prior to the actual migration.",
|
"migration_ldap_backup_before_migration": "Creating a backup of LDAP database and apps settings prior to the actual migration.",
|
||||||
"migration_ldap_can_not_backup_before_migration": "The backup of the system could not be completed before the migration failed. Error: {error}",
|
"migration_ldap_can_not_backup_before_migration": "The backup of the system could not be completed before the migration failed. Error: {error}",
|
||||||
"migration_ldap_migration_failed_trying_to_rollback": "Could not migrate… trying to roll back the system.",
|
"migration_ldap_migration_failed_trying_to_rollback": "Could not migrate… trying to roll back the system.",
|
||||||
|
|
102
locales/eu.json
102
locales/eu.json
|
@ -36,7 +36,7 @@
|
||||||
"diagnosis_http_bad_status_code": "Zerbitzari hau ez den beste gailu batek erantzun omen dio eskaerari (agian routerrak).<br>1. Honen arrazoi ohikoena 80 (eta 443) ataka <a href='https://yunohost.org/isp_box_config'>zerbitzarira ondo birbidaltzen ez dela</a> da.<br>2. Konfigurazio konplexua badarabilzu, egiaztatu suebakiak edo reverse-proxyk oztopatzen ez dutela.",
|
"diagnosis_http_bad_status_code": "Zerbitzari hau ez den beste gailu batek erantzun omen dio eskaerari (agian routerrak).<br>1. Honen arrazoi ohikoena 80 (eta 443) ataka <a href='https://yunohost.org/isp_box_config'>zerbitzarira ondo birbidaltzen ez dela</a> da.<br>2. Konfigurazio konplexua badarabilzu, egiaztatu suebakiak edo reverse-proxyk oztopatzen ez dutela.",
|
||||||
"diagnosis_http_timeout": "Denbora agortu da sare lokaletik kanpo zure zerbitzarira konektatzeko ahaleginean. Eskuragarri ez dagoela dirudi.<br>1. 80 (eta 443) ataka <a href='https://yunohost.org/isp_box_config'>zerbitzarira modu egokian birzuzentzen ez direla da</a> ohiko zergatia.<br>2. Badaezpada egiaztatu nginx martxan dagoela.<br>3. Konfigurazio konplexuetan, egiaztatu suebakiak edo reverse-proxyk konexioa oztopatzen ez dutela.",
|
"diagnosis_http_timeout": "Denbora agortu da sare lokaletik kanpo zure zerbitzarira konektatzeko ahaleginean. Eskuragarri ez dagoela dirudi.<br>1. 80 (eta 443) ataka <a href='https://yunohost.org/isp_box_config'>zerbitzarira modu egokian birzuzentzen ez direla da</a> ohiko zergatia.<br>2. Badaezpada egiaztatu nginx martxan dagoela.<br>3. Konfigurazio konplexuetan, egiaztatu suebakiak edo reverse-proxyk konexioa oztopatzen ez dutela.",
|
||||||
"app_sources_fetch_failed": "Ezinezkoa izan da fitxategiak eskuratzea, zuzena al da URLa?",
|
"app_sources_fetch_failed": "Ezinezkoa izan da fitxategiak eskuratzea, zuzena al da URLa?",
|
||||||
"app_make_default_location_already_used": "Ezinezkoa izan da '{app}' '{domain}' domeinuan lehenestea, '{other_app}'(e)k lehendik ere erabiltzen duelako",
|
"app_make_default_location_already_used": "Ezin da '{app}' '{domain}' domeinuan lehenetsi, '{other_app}'(e)k lehendik ere erabiltzen duelako",
|
||||||
"app_already_installed_cant_change_url": "Aplikazio hau instalatuta dago dagoeneko. URLa ezin da aldatu aukera honekin. Markatu 'app changeurl' markatzeko moduan badago.",
|
"app_already_installed_cant_change_url": "Aplikazio hau instalatuta dago dagoeneko. URLa ezin da aldatu aukera honekin. Markatu 'app changeurl' markatzeko moduan badago.",
|
||||||
"diagnosis_ip_not_connected_at_all": "Badirudi zerbitzaria ez dagoela internetera konektatuta!?",
|
"diagnosis_ip_not_connected_at_all": "Badirudi zerbitzaria ez dagoela internetera konektatuta!?",
|
||||||
"app_already_up_to_date": "{app} egunean da dagoeneko",
|
"app_already_up_to_date": "{app} egunean da dagoeneko",
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
"config_validate_url": "Benetazko URL bat izan behar da",
|
"config_validate_url": "Benetazko URL bat izan behar da",
|
||||||
"app_restore_script_failed": "Errorea gertatu da aplikazioa lehengoratzeko aginduan",
|
"app_restore_script_failed": "Errorea gertatu da aplikazioa lehengoratzeko aginduan",
|
||||||
"app_upgrade_some_app_failed": "Ezinezkoa izan da aplikazio batzuk eguneratzea",
|
"app_upgrade_some_app_failed": "Ezinezkoa izan da aplikazio batzuk eguneratzea",
|
||||||
"app_install_failed": "Ezinezkoa izan da {app} instalatzea: {error}",
|
"app_install_failed": "Ezin da {app} instalatu: {error}",
|
||||||
"diagnosis_basesystem_kernel": "Zerbitzariak Linuxen {kernel_version} kernela darabil",
|
"diagnosis_basesystem_kernel": "Zerbitzariak Linuxen {kernel_version} kernela darabil",
|
||||||
"app_argument_invalid": "Aukeratu balio egoki bat '{name}' argumenturako: {error}",
|
"app_argument_invalid": "Aukeratu balio egoki bat '{name}' argumenturako: {error}",
|
||||||
"app_already_installed": "{app} instalatuta dago dagoeneko",
|
"app_already_installed": "{app} instalatuta dago dagoeneko",
|
||||||
|
@ -132,7 +132,7 @@
|
||||||
"diagnosis_http_could_not_diagnose": "Ezinezkoa izan da domeinuak IPv{ipversion} kanpotik eskuragarri dauden egiaztatzea.",
|
"diagnosis_http_could_not_diagnose": "Ezinezkoa izan da domeinuak IPv{ipversion} kanpotik eskuragarri dauden egiaztatzea.",
|
||||||
"diagnosis_http_ok": "{domain} domeinua HTTP bidez bisitatu daiteke sare lokaletik kanpo.",
|
"diagnosis_http_ok": "{domain} domeinua HTTP bidez bisitatu daiteke sare lokaletik kanpo.",
|
||||||
"diagnosis_http_unreachable": "Badirudi {domain} domeinua ez dagoela eskuragarri HTTP bidez sare lokaletik kanpo.",
|
"diagnosis_http_unreachable": "Badirudi {domain} domeinua ez dagoela eskuragarri HTTP bidez sare lokaletik kanpo.",
|
||||||
"apps_catalog_failed_to_download": "Ezinezkoa izan da {apps_catalog} aplikazioen zerrenda eskuratzea: {error}",
|
"apps_catalog_failed_to_download": "Ezin da {apps_catalog} aplikazioen zerrenda eskuratu: {error}",
|
||||||
"apps_catalog_init_success": "Abiarazi da aplikazioen katalogo sistema!",
|
"apps_catalog_init_success": "Abiarazi da aplikazioen katalogo sistema!",
|
||||||
"apps_catalog_obsolete_cache": "Aplikazioen katalogoaren katxea hutsik edo zaharkituta dago.",
|
"apps_catalog_obsolete_cache": "Aplikazioen katalogoaren katxea hutsik edo zaharkituta dago.",
|
||||||
"diagnosis_description_mail": "Posta elektronikoa",
|
"diagnosis_description_mail": "Posta elektronikoa",
|
||||||
|
@ -148,18 +148,18 @@
|
||||||
"diagnosis_http_hairpinning_issue": "Dirudienez zure sareak ez du hairpinninga gaituta.",
|
"diagnosis_http_hairpinning_issue": "Dirudienez zure sareak ez du hairpinninga gaituta.",
|
||||||
"diagnosis_http_partially_unreachable": "Badirudi {domain} domeinua ezin dela bisitatu HTTP bidez IPv{failed} sare lokaletik kanpo, bai ordea IPv{passed} erabiliz.",
|
"diagnosis_http_partially_unreachable": "Badirudi {domain} domeinua ezin dela bisitatu HTTP bidez IPv{failed} sare lokaletik kanpo, bai ordea IPv{passed} erabiliz.",
|
||||||
"backup_archive_cant_retrieve_info_json": "Ezinezkoa izan da '{archive}' fitxategiko informazioa eskuratzea… info.json fitxategia ezin izan da eskuratu (edo ez da baliozko json-a).",
|
"backup_archive_cant_retrieve_info_json": "Ezinezkoa izan da '{archive}' fitxategiko informazioa eskuratzea… info.json fitxategia ezin izan da eskuratu (edo ez da baliozko json-a).",
|
||||||
"diagnosis_domain_expiration_not_found": "Ezinezkoa izan da domeinu batzuen iraungitze data egiaztatzea",
|
"diagnosis_domain_expiration_not_found": "Ezin da domeinu batzuen iraungitze data egiaztatu",
|
||||||
"diagnosis_domain_expiration_not_found_details": "Badirudi {domain} domeinuari buruzko WHOIS informazioak ez duela zehazten noiz iraungiko den?",
|
"diagnosis_domain_expiration_not_found_details": "Badirudi {domain} domeinuari buruzko WHOIS informazioak ez duela zehazten noiz iraungiko den?",
|
||||||
"certmanager_domain_not_diagnosed_yet": "Oraindik ez dago {domain} domeinurako diagnostikorik. Berrabiarazi diagnostikoak 'DNS balioak' eta 'Web' ataletarako diagnostikoen gunean Let's Encrypt ziurtagirirako prest ote dagoen egiaztatzeko. (Edo zertan ari zaren baldin badakizu, erabili '--no-checks' egiaztatzea desgaitzeko.)",
|
"certmanager_domain_not_diagnosed_yet": "Oraindik ez dago {domain} domeinurako diagnostikorik. Berrabiarazi diagnostikoak 'DNS balioak' eta 'Web' ataletarako diagnostikoen gunean Let's Encrypt ziurtagirirako prest ote dagoen egiaztatzeko. (Edo zertan ari zaren baldin badakizu, erabili '--no-checks' egiaztatzea desgaitzeko.)",
|
||||||
"diagnosis_domain_expiration_warning": "Domeinu batzuk iraungitzear daude!",
|
"diagnosis_domain_expiration_warning": "Domeinu batzuk iraungitzear daude!",
|
||||||
"app_packaging_format_not_supported": "Aplikazio hau ezin da instalatu YunoHostek ez duelako paketea ezagutzen. Sistema eguneratzea hausnartu beharko zenuke ziur asko.",
|
"app_packaging_format_not_supported": "Aplikazio hau ezin da instalatu YunoHostek ez duelako paketea ezagutzen. Sistema eguneratzea hausnartu beharko zenuke ziur asko.",
|
||||||
"diagnosis_dns_try_dyndns_update_force": "Domeinu honen DNS konfigurazioa YunoHostek kudeatu beharko luke automatikoki. Gertatuko ez balitz, eguneratzera behartu zenezake <cmd>yunohost dyndns update --force</cmd> erabiliz.",
|
"diagnosis_dns_try_dyndns_update_force": "Domeinu honen DNS konfigurazioa YunoHostek kudeatu beharko luke automatikoki. Gertatuko ez balitz, eguneratzera behartu zenezake <cmd>yunohost dyndns update --force</cmd> erabiliz.",
|
||||||
"app_manifest_install_ask_path": "Aukeratu aplikazio hau instalatzeko URLaren bidea (domeinuaren atzeko aldean)",
|
"app_manifest_install_ask_path": "Aukeratu aplikazio hau instalatzeko URLaren bidea (domeinuaren atzeko aldean)",
|
||||||
"app_manifest_install_ask_admin": "Aukeratu administrari bat aplikazio honetarako",
|
"app_manifest_install_ask_admin": "Aukeratu administratzaile bat aplikazio honetarako",
|
||||||
"app_manifest_install_ask_password": "Aukeratu administrazio-pasahitz bat aplikazio honetarako",
|
"app_manifest_install_ask_password": "Aukeratu administrazio-pasahitz bat aplikazio honetarako",
|
||||||
"ask_user_domain": "Erabiltzailearen posta elektroniko eta XMPP konturako erabiliko den domeinua",
|
"ask_user_domain": "Erabiltzailearen posta elektroniko eta XMPP konturako erabiliko den domeinua",
|
||||||
"app_action_cannot_be_ran_because_required_services_down": "{services} zerbitzuak martxan egon beharko lirateke eragiketa hau exekutatu ahal izateko. Saia zaitez zerbitzuok berrabiarazten (eta ikertu zergatik ez diren abiarazi).",
|
"app_action_cannot_be_ran_because_required_services_down": "{services} zerbitzuak martxan egon beharko lirateke eragiketa hau exekutatu ahal izateko. Saia zaitez zerbitzuok berrabiarazten (eta ikertu zergatik ez diren abiarazi).",
|
||||||
"apps_already_up_to_date": "Egunean daude dagoeneko aplikazio guztiak",
|
"apps_already_up_to_date": "Aplikazio guztiak egunean daude dagoeneko",
|
||||||
"app_full_domain_unavailable": "Aplikazio honek bere domeinu propioa behar du, baina beste aplikazio batzuk daude dagoeneko instalatuta '{domain}' domeinuan. Azpidomeinu bat erabil zenezake instalatu nahi duzun aplikaziorako.",
|
"app_full_domain_unavailable": "Aplikazio honek bere domeinu propioa behar du, baina beste aplikazio batzuk daude dagoeneko instalatuta '{domain}' domeinuan. Azpidomeinu bat erabil zenezake instalatu nahi duzun aplikaziorako.",
|
||||||
"app_install_script_failed": "Errore bat gertatu da aplikazioaren instalatzailearen aginduetan",
|
"app_install_script_failed": "Errore bat gertatu da aplikazioaren instalatzailearen aginduetan",
|
||||||
"diagnosis_basesystem_host": "Zerbitzariak Debian {debian_version} darabil",
|
"diagnosis_basesystem_host": "Zerbitzariak Debian {debian_version} darabil",
|
||||||
|
@ -263,14 +263,14 @@
|
||||||
"log_user_import": "Inportatu erabiltzaileak",
|
"log_user_import": "Inportatu erabiltzaileak",
|
||||||
"diagnosis_mail_fcrdns_ok": "Alderantzizko DNSa zuzen konfiguratuta dago!",
|
"diagnosis_mail_fcrdns_ok": "Alderantzizko DNSa zuzen konfiguratuta dago!",
|
||||||
"diagnosis_mail_queue_unavailable_details": "Errorea: {error}",
|
"diagnosis_mail_queue_unavailable_details": "Errorea: {error}",
|
||||||
"dyndns_provider_unreachable": "Ezinezkoa izan da DynDNS {provider} enpresarekin konektatzea: agian zure YunoHost zerbitzaria ez dago internetera konektatuta edo dynette zerbitzaria ez dago martxan.",
|
"dyndns_provider_unreachable": "Ezin da DynDNS {provider} enpresarekin konektatu: agian zure YunoHost zerbitzaria ez dago internetera konektatuta edo dynette zerbitzaria ez dago martxan.",
|
||||||
"extracting": "Ateratzen…",
|
"extracting": "Ateratzen…",
|
||||||
"diagnosis_ports_unreachable": "{port}. ataka ez dago eskuragarri kanpotik.",
|
"diagnosis_ports_unreachable": "{port}. ataka ez dago eskuragarri kanpotik.",
|
||||||
"diagnosis_regenconf_manually_modified_details": "Ez dago arazorik zertan ari zaren baldin badakizu! YunoHostek fitxategi hau automatikoki eguneratzeari utziko dio… Baina kontuan izan YunoHosten eguneraketek aldaketa garrantzitsuak izan ditzaketela. Nahi izatekotan, desberdintasunak aztertu ditzakezu <cmd>yunohost tools regen-conf {category} --dry-run --with-diff</cmd> komandoa exekutatuz, eta gomendatutako konfiguraziora bueltatu <cmd>yunohost tools regen-conf {category} --force</cmd> erabiliz",
|
"diagnosis_regenconf_manually_modified_details": "Ez dago arazorik zertan ari zaren baldin badakizu! YunoHostek fitxategi hau automatikoki eguneratzeari utziko dio… Baina kontuan izan YunoHosten eguneraketek aldaketa garrantzitsuak izan ditzaketela. Nahi izatekotan, desberdintasunak aztertu ditzakezu <cmd>yunohost tools regen-conf {category} --dry-run --with-diff</cmd> komandoa exekutatuz, eta gomendatutako konfiguraziora bueltatu <cmd>yunohost tools regen-conf {category} --force</cmd> erabiliz",
|
||||||
"dyndns_domain_not_provided": "{provider} DynDNS enpresak ezin du {domain} domeinua eskaini.",
|
"dyndns_domain_not_provided": "{provider} DynDNS enpresak ezin du {domain} domeinua eskaini.",
|
||||||
"firewall_reload_failed": "Ezinezkoa izan da suebakia birkargatzea",
|
"firewall_reload_failed": "Ezinezkoa izan da suebakia birkargatzea",
|
||||||
"hook_name_unknown": "'{name}' 'hook' izen ezezaguna",
|
"hook_name_unknown": "'{name}' 'hook' izen ezezaguna",
|
||||||
"domain_deletion_failed": "Ezinezkoa izan da {domain} ezabatzea: {error}",
|
"domain_deletion_failed": "Ezin da {domain} ezabatu: {error}",
|
||||||
"log_regen_conf": "Berregin '{}' sistemaren konfigurazioa",
|
"log_regen_conf": "Berregin '{}' sistemaren konfigurazioa",
|
||||||
"dpkg_lock_not_available": "Ezin da komando hau une honetan exekutatu beste aplikazio batek dpkg (sistemaren paketeen kudeatzailea) blokeatuta duelako, erabiltzen ari baita",
|
"dpkg_lock_not_available": "Ezin da komando hau une honetan exekutatu beste aplikazio batek dpkg (sistemaren paketeen kudeatzailea) blokeatuta duelako, erabiltzen ari baita",
|
||||||
"group_created": "'{group}' taldea sortu da",
|
"group_created": "'{group}' taldea sortu da",
|
||||||
|
@ -351,7 +351,7 @@
|
||||||
"diagnosis_mail_queue_unavailable": "Ezinezkoa da ilaran zenbat posta elektroniko dauden kontsultatzea",
|
"diagnosis_mail_queue_unavailable": "Ezinezkoa da ilaran zenbat posta elektroniko dauden kontsultatzea",
|
||||||
"log_user_create": "Gehitu '{}' erabiltzailea",
|
"log_user_create": "Gehitu '{}' erabiltzailea",
|
||||||
"group_cannot_edit_visitors": "'bisitariak' taldea ezin da eskuz moldatu. Saiorik hasi gabeko bisitariak barne hartzen dituen talde berezia da",
|
"group_cannot_edit_visitors": "'bisitariak' taldea ezin da eskuz moldatu. Saiorik hasi gabeko bisitariak barne hartzen dituen talde berezia da",
|
||||||
"diagnosis_ram_verylow": "Sistemak RAM memoriaren {available} baino ez ditu erabilgarri; memoria guztiaren ({total}) %{available_percent}a bakarrik!",
|
"diagnosis_ram_verylow": "Sistemak RAM memoriaren {available} baino ez ditu erabilgarri; memoria guztiaren ({total}) %{available_percent}a.",
|
||||||
"diagnosis_ram_low": "Sistemak RAM memoriaren {available} ditu erabilgarri; memoria guztiaren ({total}) %{available_percent}a. Adi ibili.",
|
"diagnosis_ram_low": "Sistemak RAM memoriaren {available} ditu erabilgarri; memoria guztiaren ({total}) %{available_percent}a. Adi ibili.",
|
||||||
"diagnosis_ram_ok": "Sistemak RAM memoriaren {available} ditu oraindik erabilgarri; memoria guztiaren ({total}) %{available_percent}a.",
|
"diagnosis_ram_ok": "Sistemak RAM memoriaren {available} ditu oraindik erabilgarri; memoria guztiaren ({total}) %{available_percent}a.",
|
||||||
"diagnosis_swap_none": "Sistemak ez du swap-ik. Gutxienez {recommended} izaten saiatu beharko zinateke, sistema memoriarik gabe gera ez dadin.",
|
"diagnosis_swap_none": "Sistemak ez du swap-ik. Gutxienez {recommended} izaten saiatu beharko zinateke, sistema memoriarik gabe gera ez dadin.",
|
||||||
|
@ -387,7 +387,7 @@
|
||||||
"diagnosis_mail_outgoing_port_25_ok": "SMTP posta zerbitzaria posta elektronikoa bidaltzeko gai da (25. atakaren irteera ez dago blokeatuta).",
|
"diagnosis_mail_outgoing_port_25_ok": "SMTP posta zerbitzaria posta elektronikoa bidaltzeko gai da (25. atakaren irteera ez dago blokeatuta).",
|
||||||
"diagnosis_ports_partially_unreachable": "{port}. ataka ez dago eskuragarri kanpotik IPv{failed} erabiliz.",
|
"diagnosis_ports_partially_unreachable": "{port}. ataka ez dago eskuragarri kanpotik IPv{failed} erabiliz.",
|
||||||
"diagnosis_ports_forwarding_tip": "Arazoa konpontzeko, litekeena da operadorearen routerrean ataken birbideraketa konfiguratu behar izatea, <a href='https://yunohost.org/isp_box_config'>https://yunohost.org/isp_box_config</a>-n agertzen den bezala",
|
"diagnosis_ports_forwarding_tip": "Arazoa konpontzeko, litekeena da operadorearen routerrean ataken birbideraketa konfiguratu behar izatea, <a href='https://yunohost.org/isp_box_config'>https://yunohost.org/isp_box_config</a>-n agertzen den bezala",
|
||||||
"domain_creation_failed": "Ezinezkoa izan da {domain} domeinua sortzea: {error}",
|
"domain_creation_failed": "Ezin da {domain} domeinua sortu: {error}",
|
||||||
"domains_available": "Erabilgarri dauden domeinuak:",
|
"domains_available": "Erabilgarri dauden domeinuak:",
|
||||||
"group_already_exist_on_system": "{group} taldea existitzen da dagoeneko sistemaren taldeetan",
|
"group_already_exist_on_system": "{group} taldea existitzen da dagoeneko sistemaren taldeetan",
|
||||||
"diagnosis_processes_killed_by_oom_reaper": "Memoria agortu eta sistemak prozesu batzuk amaituarazi behar izan ditu. Honek esan nahi du sistemak ez duela memoria nahikoa edo prozesuren batek memoria gehiegi behar duela. Amaituarazi d(ir)en prozesua(k):\n{kills_summary}",
|
"diagnosis_processes_killed_by_oom_reaper": "Memoria agortu eta sistemak prozesu batzuk amaituarazi behar izan ditu. Honek esan nahi du sistemak ez duela memoria nahikoa edo prozesuren batek memoria gehiegi behar duela. Amaituarazi d(ir)en prozesua(k):\n{kills_summary}",
|
||||||
|
@ -400,7 +400,7 @@
|
||||||
"domain_cannot_remove_main": "Ezin duzu '{domain}' ezabatu domeinu nagusia delako. Beste domeinu bat ezarri beharko duzu nagusi bezala 'yunohost domain main-domain -n <another-domain>' erabiliz; honako hauek dituzu aukeran: {other_domains}",
|
"domain_cannot_remove_main": "Ezin duzu '{domain}' ezabatu domeinu nagusia delako. Beste domeinu bat ezarri beharko duzu nagusi bezala 'yunohost domain main-domain -n <another-domain>' erabiliz; honako hauek dituzu aukeran: {other_domains}",
|
||||||
"domain_created": "Sortu da domeinua",
|
"domain_created": "Sortu da domeinua",
|
||||||
"domain_dyndns_already_subscribed": "Dagoeneko izena eman duzu DynDNS domeinu batean",
|
"domain_dyndns_already_subscribed": "Dagoeneko izena eman duzu DynDNS domeinu batean",
|
||||||
"domain_hostname_failed": "Ezinezkoa izan da hostname berria ezartzea. Honek arazoak ekar litzake etorkizunean (litekeena da ondo egotea).",
|
"domain_hostname_failed": "Ezin da hostname berria ezarri. Honek arazoak ekar litzake etorkizunean (litekeena da ondo egotea).",
|
||||||
"domain_uninstall_app_first": "Honako aplikazio hauek domeinuan instalatuta daude:\n{apps}\n\nDesinstalatu 'yunohost app remove the_app_id' exekutatuz edo alda itzazu beste domeinu batera 'yunohost app change-url the_app_id' erabiliz domeinua ezabatu baino lehen",
|
"domain_uninstall_app_first": "Honako aplikazio hauek domeinuan instalatuta daude:\n{apps}\n\nDesinstalatu 'yunohost app remove the_app_id' exekutatuz edo alda itzazu beste domeinu batera 'yunohost app change-url the_app_id' erabiliz domeinua ezabatu baino lehen",
|
||||||
"file_does_not_exist": "{path} fitxategia ez da existitzen.",
|
"file_does_not_exist": "{path} fitxategia ez da existitzen.",
|
||||||
"firewall_rules_cmd_failed": "Suebakiko arau batzuen exekuzioak huts egin du. Informazio gehiago erregistroetan.",
|
"firewall_rules_cmd_failed": "Suebakiko arau batzuen exekuzioak huts egin du. Informazio gehiago erregistroetan.",
|
||||||
|
@ -423,7 +423,7 @@
|
||||||
"domain_cert_gen_failed": "Ezinezkoa izan da ziurtagiria sortzea",
|
"domain_cert_gen_failed": "Ezinezkoa izan da ziurtagiria sortzea",
|
||||||
"field_invalid": "'{}' ez da baliogarria",
|
"field_invalid": "'{}' ez da baliogarria",
|
||||||
"diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Operadore batzuei bost axola zaie internetaren neutraltasuna (Net Neutrality) eta ez dute 25. ataka desblokeatzen uzten.<br>- Operadore batzuek <a href='https://yunohost.org/email_configure_relay'>relay posta zerbitzari bat</a> eskaini dezakete, baina kasu horretan zure posta elektronikoa zelatatu dezakete.<br>- Pribatutasuna bermatzeko *IP publikoa* duen VPN bat erabiltzea izan daiteke irtenbidea. Ikus <a href='https://yunohost.org/vpn_advantage'>https://yunohost.org/vpn_advantage</a><br>- Edo <a href='https://yunohost.org/isp'>operadore desberdin batera aldatu</a>",
|
"diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Operadore batzuei bost axola zaie internetaren neutraltasuna (Net Neutrality) eta ez dute 25. ataka desblokeatzen uzten.<br>- Operadore batzuek <a href='https://yunohost.org/email_configure_relay'>relay posta zerbitzari bat</a> eskaini dezakete, baina kasu horretan zure posta elektronikoa zelatatu dezakete.<br>- Pribatutasuna bermatzeko *IP publikoa* duen VPN bat erabiltzea izan daiteke irtenbidea. Ikus <a href='https://yunohost.org/vpn_advantage'>https://yunohost.org/vpn_advantage</a><br>- Edo <a href='https://yunohost.org/isp'>operadore desberdin batera aldatu</a>",
|
||||||
"ldap_server_down": "Ezin izan da LDAP zerbitzarira konektatu",
|
"ldap_server_down": "Ezin da LDAP zerbitzarira konektatu",
|
||||||
"ldap_server_is_down_restart_it": "LDAP zerbitzaria ez dago martxan, saia zaitez berrabiarazten…",
|
"ldap_server_is_down_restart_it": "LDAP zerbitzaria ez dago martxan, saia zaitez berrabiarazten…",
|
||||||
"log_app_upgrade": "'{}' aplikazioa eguneratu",
|
"log_app_upgrade": "'{}' aplikazioa eguneratu",
|
||||||
"log_tools_shutdown": "Itzali zerbitzaria",
|
"log_tools_shutdown": "Itzali zerbitzaria",
|
||||||
|
@ -461,7 +461,7 @@
|
||||||
"user_import_success": "Erabiltzaileak arazorik gabe inportatu dira",
|
"user_import_success": "Erabiltzaileak arazorik gabe inportatu dira",
|
||||||
"yunohost_already_installed": "YunoHost instalatuta dago dagoeneko",
|
"yunohost_already_installed": "YunoHost instalatuta dago dagoeneko",
|
||||||
"migrations_success_forward": "{id} migrazioak amaitu du",
|
"migrations_success_forward": "{id} migrazioak amaitu du",
|
||||||
"migrations_to_be_ran_manually": "{id} migrazioa eskuz abiarazi behar da. Joan Tresnak → Migrazioak atalera administrazio-atarian edo bestela exekutatu 'yunohost tools migrations run'.",
|
"migrations_to_be_ran_manually": "{id} migrazioa eskuz abiarazi behar da. Joan Tresnak → Migrazioak atalera administrazio-gunean edo bestela exekutatu 'yunohost tools migrations run'.",
|
||||||
"permission_currently_allowed_for_all_users": "Baimen hau erabiltzaile guztiei esleitzen zaie eta baita beste talde batzuei ere. Litekeena da 'all users' baimena edo esleituta duten taldeei baimena kendu nahi izatea.",
|
"permission_currently_allowed_for_all_users": "Baimen hau erabiltzaile guztiei esleitzen zaie eta baita beste talde batzuei ere. Litekeena da 'all users' baimena edo esleituta duten taldeei baimena kendu nahi izatea.",
|
||||||
"permission_require_account": "'{permission}' baimena zerbitzarian kontua duten erabiltzaileentzat da eta, beraz, ezin da gaitu bisitarientzat.",
|
"permission_require_account": "'{permission}' baimena zerbitzarian kontua duten erabiltzaileentzat da eta, beraz, ezin da gaitu bisitarientzat.",
|
||||||
"postinstall_low_rootfsspace": "'root' fitxategi-sistemak 10 GB edo espazio gutxiago dauka, kezkatzekoa dena! Litekeena da espaziorik gabe geratzea aurki! Gomendagarria da 'root' fitxategi-sistemak gutxienez 16 GB libre izatea. Jakinarazpen honen ondoren YunoHost instalatzen jarraitu nahi baduzu, berrabiarazi agindua '--force-diskspace' gehituz",
|
"postinstall_low_rootfsspace": "'root' fitxategi-sistemak 10 GB edo espazio gutxiago dauka, kezkatzekoa dena! Litekeena da espaziorik gabe geratzea aurki! Gomendagarria da 'root' fitxategi-sistemak gutxienez 16 GB libre izatea. Jakinarazpen honen ondoren YunoHost instalatzen jarraitu nahi baduzu, berrabiarazi agindua '--force-diskspace' gehituz",
|
||||||
|
@ -515,7 +515,7 @@
|
||||||
"service_disable_failed": "Ezin izan da '{service}' zerbitzua geldiarazi zerbitzaria abiaraztean.\n\nZerbitzuen erregistro berrienak: {logs}",
|
"service_disable_failed": "Ezin izan da '{service}' zerbitzua geldiarazi zerbitzaria abiaraztean.\n\nZerbitzuen erregistro berrienak: {logs}",
|
||||||
"migrations_skip_migration": "{id} migrazioa saihesten…",
|
"migrations_skip_migration": "{id} migrazioa saihesten…",
|
||||||
"upnp_disabled": "UPnP itzalita dago",
|
"upnp_disabled": "UPnP itzalita dago",
|
||||||
"main_domain_change_failed": "Ezinezkoa izan da domeinu nagusia aldatzea",
|
"main_domain_change_failed": "Ezin da domeinu nagusia aldatu",
|
||||||
"regenconf_failed": "Ezinezkoa izan da ondorengo atal(ar)en konfigurazioa berregitea: {categories}",
|
"regenconf_failed": "Ezinezkoa izan da ondorengo atal(ar)en konfigurazioa berregitea: {categories}",
|
||||||
"pattern_email_forward": "Helbide elektroniko baliagarri bat izan behar da, '+' karakterea onartzen da (adibidez: izena+urtea@domeinua.eus)",
|
"pattern_email_forward": "Helbide elektroniko baliagarri bat izan behar da, '+' karakterea onartzen da (adibidez: izena+urtea@domeinua.eus)",
|
||||||
"regenconf_file_manually_removed": "'{conf}' konfigurazio fitxategia eskuz ezabatu da eta ez da berriro sortuko",
|
"regenconf_file_manually_removed": "'{conf}' konfigurazio fitxategia eskuz ezabatu da eta ez da berriro sortuko",
|
||||||
|
@ -579,7 +579,7 @@
|
||||||
"port_already_opened": "{port}. ataka dagoeneko irekita dago {ip_version} konexioetarako",
|
"port_already_opened": "{port}. ataka dagoeneko irekita dago {ip_version} konexioetarako",
|
||||||
"user_home_creation_failed": "Ezin izan da erabiltzailearentzat '{home}' direktorioa sortu",
|
"user_home_creation_failed": "Ezin izan da erabiltzailearentzat '{home}' direktorioa sortu",
|
||||||
"user_unknown": "Erabiltzaile ezezaguna: {user}",
|
"user_unknown": "Erabiltzaile ezezaguna: {user}",
|
||||||
"yunohost_postinstall_end_tip": "Instalazio ondorengo prozesua amaitu da! Sistemaren konfigurazioa bukatzeko:\n- erabili 'Diagnostikoak' gunea ohiko arazoei aurre hartzeko. Administrazio-atarian abiarazi edo 'yunohost diagnosis run' exekutatu;\n- irakurri 'Finalizing your setup' eta 'Getting to know YunoHost' atalak. Dokumentazioan aurki ditzakezu: https://yunohost.org/admindoc.",
|
"yunohost_postinstall_end_tip": "Instalazio ondorengo prozesua amaitu da! Sistemaren konfigurazioa bukatzeko:\n- erabili 'Diagnostikoak' gunea ohiko arazoei aurre hartzeko. Abiarazi administrazio-gunean edo exekutatu 'yunohost diagnosis run';\n- irakurri 'Finalizing your setup' eta 'Getting to know YunoHost' atalak. Dokumentazioan aurki ditzakezu: https://yunohost.org/admindoc.",
|
||||||
"yunohost_not_installed": "YunoHost ez da zuzen instalatu. Exekutatu 'yunohost tools postinstall'",
|
"yunohost_not_installed": "YunoHost ez da zuzen instalatu. Exekutatu 'yunohost tools postinstall'",
|
||||||
"unlimit": "Mugarik ez",
|
"unlimit": "Mugarik ez",
|
||||||
"restore_already_installed_apps": "Ondorengo aplikazioak ezin dira lehengoratu dagoeneko instalatuta daudelako: {apps}",
|
"restore_already_installed_apps": "Ondorengo aplikazioak ezin dira lehengoratu dagoeneko instalatuta daudelako: {apps}",
|
||||||
|
@ -590,9 +590,9 @@
|
||||||
"migration_ldap_rollback_success": "Sistema lehengoratu da.",
|
"migration_ldap_rollback_success": "Sistema lehengoratu da.",
|
||||||
"regenconf_need_to_explicitly_specify_ssh": "SSH ezarpenak eskuz aldatu dira, baina aldaketak erabiltzeko '--force' zehaztu behar duzu 'ssh' atalean.",
|
"regenconf_need_to_explicitly_specify_ssh": "SSH ezarpenak eskuz aldatu dira, baina aldaketak erabiltzeko '--force' zehaztu behar duzu 'ssh' atalean.",
|
||||||
"regex_incompatible_with_tile": "/!\\ Pakete-arduradunak! {permission}' baimenak show_tile aukera 'true' bezala dauka eta horregatik ezin duzue regex URLa URL nagusi bezala ezarri",
|
"regex_incompatible_with_tile": "/!\\ Pakete-arduradunak! {permission}' baimenak show_tile aukera 'true' bezala dauka eta horregatik ezin duzue regex URLa URL nagusi bezala ezarri",
|
||||||
"root_password_desynchronized": "Administrariaren pasahitza aldatu da baina YunoHostek ezin izan du aldaketa root pasahitzera hedatu!",
|
"root_password_desynchronized": "Administratzailearen pasahitza aldatu da baina YunoHostek ezin izan du aldaketa root pasahitzera hedatu!",
|
||||||
"server_shutdown": "Zerbitzaria itzaliko da",
|
"server_shutdown": "Zerbitzaria itzaliko da",
|
||||||
"service_stop_failed": "Ezin izan da '{service}' zerbitzua geldiarazi\n\nZerbitzuen azken erregistroak: {logs}",
|
"service_stop_failed": "Ezin da '{service}' zerbitzua geldiarazi\n\nZerbitzuaren azken erregistroak: {logs}",
|
||||||
"service_unknown": "'{service}' zerbitzu ezezaguna",
|
"service_unknown": "'{service}' zerbitzu ezezaguna",
|
||||||
"show_tile_cant_be_enabled_for_url_not_defined": "Ezin duzu 'show_tile' gaitu une honetan, '{permission}' baimenerako URL bat zehaztu behar duzulako",
|
"show_tile_cant_be_enabled_for_url_not_defined": "Ezin duzu 'show_tile' gaitu une honetan, '{permission}' baimenerako URL bat zehaztu behar duzulako",
|
||||||
"upnp_enabled": "UPnP piztuta dago",
|
"upnp_enabled": "UPnP piztuta dago",
|
||||||
|
@ -601,8 +601,8 @@
|
||||||
"restore_hook_unavailable": "'{part}'-(e)rako lehengoratze agindua ez dago erabilgarri ez sisteman ezta fitxategian ere",
|
"restore_hook_unavailable": "'{part}'-(e)rako lehengoratze agindua ez dago erabilgarri ez sisteman ezta fitxategian ere",
|
||||||
"restore_cleaning_failed": "Ezin izan dira lehengoratzeko behin-behineko fitxategiak ezabatu",
|
"restore_cleaning_failed": "Ezin izan dira lehengoratzeko behin-behineko fitxategiak ezabatu",
|
||||||
"restore_confirm_yunohost_installed": "Ziur al zaude dagoeneko instalatuta dagoen sistema lehengoratu nahi duzula? [{answers}]",
|
"restore_confirm_yunohost_installed": "Ziur al zaude dagoeneko instalatuta dagoen sistema lehengoratu nahi duzula? [{answers}]",
|
||||||
"restore_may_be_not_enough_disk_space": "Badirudi zure sistemak ez duela nahikoa espazio (erabilgarri: {free_space} B, beharrezkoa {needed_space} B, segurtasuneko tartea: {margin} B)",
|
"restore_may_be_not_enough_disk_space": "Badirudi zure sistemak ez duela nahikoa espazio (erabilgarri: {free_space} B, beharrezkoa {needed_space} B, segurtasun-tartea: {margin} B)",
|
||||||
"restore_not_enough_disk_space": "Ez dago nahikoa espazio (erabilgarri: {free_space} B, beharrezkoa {needed_space} B, segurtasuneko tartea: {margin} B)",
|
"restore_not_enough_disk_space": "Ez dago nahikoa espazio (erabilgarri: {free_space} B, beharrezkoa {needed_space} B, segurtasun-tartea: {margin} B)",
|
||||||
"restore_running_hooks": "Lehengoratzeko 'hook'ak exekutatzen…",
|
"restore_running_hooks": "Lehengoratzeko 'hook'ak exekutatzen…",
|
||||||
"restore_system_part_failed": "Ezinezkoa izan da sistemaren '{part}' atala lehengoratzea",
|
"restore_system_part_failed": "Ezinezkoa izan da sistemaren '{part}' atala lehengoratzea",
|
||||||
"server_reboot": "Zerbitzaria berrabiaraziko da",
|
"server_reboot": "Zerbitzaria berrabiaraziko da",
|
||||||
|
@ -620,24 +620,24 @@
|
||||||
"service_description_redis-server": "Datuak bizkor atzitzeko, zereginak lerratzeko eta programen arteko komunikaziorako datubase berezi bat da",
|
"service_description_redis-server": "Datuak bizkor atzitzeko, zereginak lerratzeko eta programen arteko komunikaziorako datubase berezi bat da",
|
||||||
"service_description_rspamd": "Spama bahetu eta posta elektronikoarekin zerikusia duten bestelako futzioen ardura dauka",
|
"service_description_rspamd": "Spama bahetu eta posta elektronikoarekin zerikusia duten bestelako futzioen ardura dauka",
|
||||||
"service_description_slapd": "Erabiltzaileak, domeinuak eta hauei lotutako informazioa gordetzen du",
|
"service_description_slapd": "Erabiltzaileak, domeinuak eta hauei lotutako informazioa gordetzen du",
|
||||||
"service_description_yunohost-api": "YunoHosten web-atariaren eta sistemaren arteko hartuemana kudeatzen du",
|
"service_description_yunohost-api": "YunoHosten web-interfazearen eta sistemaren arteko hartuemana kudeatzen du",
|
||||||
"domain_config_default_app": "Lehenetsitako aplikazioa",
|
"domain_config_default_app": "Lehenetsitako aplikazioa",
|
||||||
"tools_upgrade": "Sistemaren paketeak eguneratzen",
|
"tools_upgrade": "Sistemaren paketeak eguneratzen",
|
||||||
"tools_upgrade_failed": "Ezin izan dira paketeak eguneratu: {packages_list}",
|
"tools_upgrade_failed": "Ezin izan dira paketeak eguneratu: {packages_list}",
|
||||||
"service_description_postgresql": "Aplikazioen datuak gordetzen ditu (SQL datubasea)",
|
"service_description_postgresql": "Aplikazioen datuak gordetzen ditu (SQL datubasea)",
|
||||||
"migration_0021_start": "Bullseye (e)rako migrazioa abiarazten",
|
"migration_0021_start": "Bullseye-rako migrazioa abiarazten",
|
||||||
"migration_0021_patching_sources_list": "sources.lists petatxatzen…",
|
"migration_0021_patching_sources_list": "sources.lists petatxatzen…",
|
||||||
"migration_0021_main_upgrade": "Eguneraketa nagusia abiarazten…",
|
"migration_0021_main_upgrade": "Eguneraketa nagusia abiarazten…",
|
||||||
"migration_0021_still_on_buster_after_main_upgrade": "Zerbaitek huts egin du eguneraketa nagusian, badirudi sistemak oraindik darabilela Debian Buster",
|
"migration_0021_still_on_buster_after_main_upgrade": "Zerbaitek huts egin du eguneraketa nagusian, badirudi sistemak oraindik darabilela Debian Buster",
|
||||||
"migration_0021_yunohost_upgrade": "YunoHosten muineko eguneraketa abiarazten…",
|
"migration_0021_yunohost_upgrade": "YunoHosten muineko bertsio-berriztea abiarazten…",
|
||||||
"migration_0021_not_enough_free_space": "/var/-enerabilgarri dagoen espazioa oso txikia da! Guxtienez GB 1 izan beharko zenuke erabilgarri migrazioari ekiteko.",
|
"migration_0021_not_enough_free_space": "/var/-en erabilgarri dagoen espazioa oso txikia da! Gutxienez GB 1 izan beharko zenuke erabilgarri migrazioari ekiteko.",
|
||||||
"migration_0021_system_not_fully_up_to_date": "Sistema ez dago erabat egunean. Egizu eguneraketa arrunt bat Bullseye-(e)rako migrazioa abiarazi baino lehen.",
|
"migration_0021_system_not_fully_up_to_date": "Sistema ez dago erabat egunean. Egizu eguneraketa arrunt bat Bullseye-rako migrazioa abiarazi baino lehen.",
|
||||||
"migration_0021_general_warning": "Kontuan hartu migrazio hau konplexua dela. YunoHost taldeak ahalegin handia egin du probatzeko, baina hala ere migrazioak sistemaren zatiren bat edo aplikazioak apurt litzake.\n\nHorregatik, gomendagarria da:\n\t- Datu edo aplikazio garrantzitsuen babeskopia egitea. Informazio gehiago: https://yunohost.org/backup;\n\t- Ez izan presarik migrazioa abiaraztean: zure internet eta hardwarearen arabera ordu batzuk ere iraun lezake eguneraketa prozesuak.",
|
"migration_0021_general_warning": "Kontuan hartu migrazio hau konplexua dela. YunoHost taldeak ahalegin handia egin du probatzeko, baina hala ere migrazioak sistemaren zatiren bat edo aplikazioak apurt litzake.\n\nHorregatik, gomendagarria da:\n\t- Datu edo aplikazio garrantzitsuen babeskopia egitea. Informazio gehiago: https://yunohost.org/backup;\n\t- Ez izan presarik migrazioa abiaraztean: zure internet eta hardwarearen arabera ordu batzuk ere iraun lezake eguneraketa prozesuak.",
|
||||||
"migration_0021_modified_files": "Kontuan hartu ondorengo fitxategiak eskuz moldatu omen direla eta eguneraketak berridatziko dituela: {manually_modified_files}",
|
"migration_0021_modified_files": "Kontuan hartu ondorengo fitxategiak eskuz moldatu omen direla eta eguneraketak berridatziko dituela: {manually_modified_files}",
|
||||||
"migration_0021_cleaning_up": "Katxea eta erabilgarriak ez diren paketeak garbitzen…",
|
"migration_0021_cleaning_up": "Katxea eta erabilgarriak ez diren paketeak garbitzen…",
|
||||||
"migration_0021_patch_yunohost_conflicts": "Arazo gatazkatsu bati adabakia jartzen…",
|
"migration_0021_patch_yunohost_conflicts": "Arazo gatazkatsu bati adabakia jartzen…",
|
||||||
"migration_description_0021_migrate_to_bullseye": "Eguneratu sistema Debian Bullseye eta Yunohost 11.x-ra",
|
"migration_description_0021_migrate_to_bullseye": "Bertsio-berritu sistema Debian Bullseye eta YunoHost 11.x-ra",
|
||||||
"migration_0021_problematic_apps_warning": "Kontuan izan ziur asko gatazkatsuak izango diren odorengo aplikazioak aurkitu direla. Badirudi ez zirela YunoHost aplikazioen katalogotik instalatu, edo ez daude 'badabiltza' bezala etiketatuak. Ondorioz, ezin da bermatu eguneratu ondoren funtzionatzen jarraituko dutenik: {problematic_apps}",
|
"migration_0021_problematic_apps_warning": "Kontuan izan ziur asko gatazkatsuak izango diren ondorengo aplikazioak aurkitu direla. Badirudi ez zirela YunoHost aplikazioen katalogotik instalatu, edo ez daude 'badabiltza' bezala etiketatuak. Ondorioz, ezin da bermatu eguneratu ondoren funtzionatzen jarraituko dutenik: {problematic_apps}",
|
||||||
"migration_0023_not_enough_space": "{path}-en ez dago toki nahikorik migrazioa abiarazteko.",
|
"migration_0023_not_enough_space": "{path}-en ez dago toki nahikorik migrazioa abiarazteko.",
|
||||||
"migration_0023_postgresql_11_not_installed": "PostgreSQL ez zegoen zure isteman instalatuta. Ez dago egitekorik.",
|
"migration_0023_postgresql_11_not_installed": "PostgreSQL ez zegoen zure isteman instalatuta. Ez dago egitekorik.",
|
||||||
"migration_0023_postgresql_13_not_installed": "PostgreSQL 11 dago instalatuta baina PostgreSQL 13 ez!? Zerbait arraroa gertatu omen zaio zure sistemari :(…",
|
"migration_0023_postgresql_13_not_installed": "PostgreSQL 11 dago instalatuta baina PostgreSQL 13 ez!? Zerbait arraroa gertatu omen zaio zure sistemari :(…",
|
||||||
|
@ -654,8 +654,8 @@
|
||||||
"global_settings_setting_ssh_password_authentication_help": "Baimendu pasahitz bidezko autentikazioa SSHrako",
|
"global_settings_setting_ssh_password_authentication_help": "Baimendu pasahitz bidezko autentikazioa SSHrako",
|
||||||
"global_settings_setting_ssh_port": "SSH ataka",
|
"global_settings_setting_ssh_port": "SSH ataka",
|
||||||
"global_settings_setting_webadmin_allowlist_help": "Administrazio-atarira sar daitezken IP helbideak. CIDR notazioa ahalbidetzen da.",
|
"global_settings_setting_webadmin_allowlist_help": "Administrazio-atarira sar daitezken IP helbideak. CIDR notazioa ahalbidetzen da.",
|
||||||
"global_settings_setting_webadmin_allowlist_enabled_help": "Baimendu IP zehatz batzuk bakarrik administrazio-atarian.",
|
"global_settings_setting_webadmin_allowlist_enabled_help": "Baimendu IP zehatz batzuk bakarrik administrazio-gunerako.",
|
||||||
"global_settings_setting_smtp_allow_ipv6_help": "Baimendu IPv6 posta elektronikoa jaso eta bidaltzeko",
|
"global_settings_setting_smtp_allow_ipv6_help": "Gaitu IPv6 posta elektronikoa jaso eta bidaltzeko",
|
||||||
"global_settings_setting_smtp_relay_enabled_help": "YunoHosten ordez posta elektronikoa bidaltzeko SMTP relay helbidea. Erabilgarri izan daiteke egoera hauetan: operadore edo VPS enpresak 25. ataka blokeatzen badu, DUHLen zure etxeko IPa ageri bada, ezin baduzu alderantzizko DNSa ezarri edo zerbitzari hau ez badago zuzenean internetera konektatuta baina posta elektronikoa bidali nahi baduzu.",
|
"global_settings_setting_smtp_relay_enabled_help": "YunoHosten ordez posta elektronikoa bidaltzeko SMTP relay helbidea. Erabilgarri izan daiteke egoera hauetan: operadore edo VPS enpresak 25. ataka blokeatzen badu, DUHLen zure etxeko IPa ageri bada, ezin baduzu alderantzizko DNSa ezarri edo zerbitzari hau ez badago zuzenean internetera konektatuta baina posta elektronikoa bidali nahi baduzu.",
|
||||||
"migration_0024_rebuild_python_venv_broken_app": "{app} aplikazioari ez ikusiarena egin zaio ezin delako ingurune birtuala modu errazean birsortu. Horren ordez, aplikazioaren eguneraketa behartzen saia zaitezke `yunohost app upgrade --force {app}` arazoa konpontzeko.",
|
"migration_0024_rebuild_python_venv_broken_app": "{app} aplikazioari ez ikusiarena egin zaio ezin delako ingurune birtuala modu errazean birsortu. Horren ordez, aplikazioaren eguneraketa behartzen saia zaitezke `yunohost app upgrade --force {app}` arazoa konpontzeko.",
|
||||||
"migration_0024_rebuild_python_venv_disclaimer_rebuild": "Ondorengo aplikazioen virtualenv-a birsortzeko saiakera egingo da (eragiketak luze jo dezake!): {rebuild_apps}",
|
"migration_0024_rebuild_python_venv_disclaimer_rebuild": "Ondorengo aplikazioen virtualenv-a birsortzeko saiakera egingo da (eragiketak luze jo dezake!): {rebuild_apps}",
|
||||||
|
@ -664,12 +664,12 @@
|
||||||
"migration_0024_rebuild_python_venv_failed": "{app} aplikazioaren Python virtualenv-aren birsorkuntza saiakerak huts egin du. Litekeena da aplikazioak ez funtzionatzea arazoa konpondu arte. Aplikazioaren eguneraketa behartu beharko zenuke ondorengo komandoarekin: `yunohost app upgrade --force {app}`.",
|
"migration_0024_rebuild_python_venv_failed": "{app} aplikazioaren Python virtualenv-aren birsorkuntza saiakerak huts egin du. Litekeena da aplikazioak ez funtzionatzea arazoa konpondu arte. Aplikazioaren eguneraketa behartu beharko zenuke ondorengo komandoarekin: `yunohost app upgrade --force {app}`.",
|
||||||
"migration_description_0024_rebuild_python_venv": "Konpondu Python aplikazioa Bullseye eguneraketa eta gero",
|
"migration_description_0024_rebuild_python_venv": "Konpondu Python aplikazioa Bullseye eguneraketa eta gero",
|
||||||
"migration_0024_rebuild_python_venv_disclaimer_base": "Debian Bullseye eguneraketa dela-eta, Python aplikazio batzuk birsortu behar dira Debianekin datorren Pythonen bertsiora egokitzeko (teknikoki 'virtualenv' deritzaiona birsortu behar da). Egin artean, litekeena da Python aplikazio horiek ez funtzionatzea. YunoHost saia daiteke beherago ageri diren aplikazioen virtualenv edo ingurune birtualak birsortzen. Beste aplikazio batzuen kasuan, edo birsortze saiakerak kale egingo balu, aplikazio horien eguneraketa behartu beharko duzu.",
|
"migration_0024_rebuild_python_venv_disclaimer_base": "Debian Bullseye eguneraketa dela-eta, Python aplikazio batzuk birsortu behar dira Debianekin datorren Pythonen bertsiora egokitzeko (teknikoki 'virtualenv' deritzaiona birsortu behar da). Egin artean, litekeena da Python aplikazio horiek ez funtzionatzea. YunoHost saia daiteke beherago ageri diren aplikazioen virtualenv edo ingurune birtualak birsortzen. Beste aplikazio batzuen kasuan, edo birsortze saiakerak kale egingo balu, aplikazio horien eguneraketa behartu beharko duzu.",
|
||||||
"migration_0021_not_buster2": "Zerbitzariak darabilen Debian bertsioa ez da Buster! Dagoeneko Buster -> Bullseye migrazioa exekutatu baduzu, errore honek migrazioa erabat arrakastatsua izan ez zela esan nahi du (bestela YunoHostek amaitutzat markatuko luke). Komenigarria izango litzateke, laguntza taldearekin batera, zer gertatu zen aztertzea. Horretarako `migrazioaren erregistro **osoa** beharko duzue, Tresnak > Erregistroak atalean eskuragarri dagoena.",
|
"migration_0021_not_buster2": "Zerbitzariak darabilen Debian bertsioa ez da Buster! Dagoeneko Buster -> Bullseye migrazioa exekutatu baduzu, errore honek migrazioa erabat arrakastatsua izan ez zela esan nahi du (bestela YunoHostek amaitutzat markatuko luke). Komenigarria izango litzateke, laguntza taldearekin batera, zer gertatu zen aztertzea. Horretarako migrazioaren erregistro **osoa** beharko duzue, Tresnak > Erregistroak atalean eskuragarri dagoena.",
|
||||||
"admins": "Administratzaileek",
|
"admins": "Administratzaileek",
|
||||||
"app_action_failed": "{app} aplikaziorako {action} eragiketak huts egin du",
|
"app_action_failed": "{app} aplikaziorako {action} eragiketak huts egin du",
|
||||||
"config_action_disabled": "Ezin izan da '{action}' eragiketa exekutatu ezgaituta dagoelako, egiaztatu bere mugak betetzen dituzula. Laguntza: {help}",
|
"config_action_disabled": "Ezin izan da '{action}' eragiketa exekutatu ezgaituta dagoelako, egiaztatu bere mugak betetzen dituzula. Laguntza: {help}",
|
||||||
"all_users": "YunoHosten erabiltzaile guztiek",
|
"all_users": "YunoHosten erabiltzaile guztiek",
|
||||||
"app_manifest_install_ask_init_admin_permission": "Nork izan beharko luke aplikazio honetako administrazio aukeretara sarbidea? (Aldatzea dago)",
|
"app_manifest_install_ask_init_admin_permission": "Nork izan beharko luke aplikazio honetako administrazio-aukeretara sarbidea? (Aldatzea dago)",
|
||||||
"app_manifest_install_ask_init_main_permission": "Nork izan beharko luke aplikazio honetara sarbidea? (Aldatzea dago)",
|
"app_manifest_install_ask_init_main_permission": "Nork izan beharko luke aplikazio honetara sarbidea? (Aldatzea dago)",
|
||||||
"ask_admin_fullname": "Administratzailearen izen osoa",
|
"ask_admin_fullname": "Administratzailearen izen osoa",
|
||||||
"ask_admin_username": "Administratzailearen erabiltzaile-izena",
|
"ask_admin_username": "Administratzailearen erabiltzaile-izena",
|
||||||
|
@ -681,7 +681,7 @@
|
||||||
"domain_config_cert_summary_expired": "LARRIA: Uneko ziurtagiria ez da baliozkoa! HTTPS ezin da erabili!",
|
"domain_config_cert_summary_expired": "LARRIA: Uneko ziurtagiria ez da baliozkoa! HTTPS ezin da erabili!",
|
||||||
"domain_config_cert_summary_selfsigned": "ADI: Uneko zirutagiria norberak sinatutakoa da. Web-nabigatzaileek bisitariak izutuko dituen mezu bat erakutsiko dute!",
|
"domain_config_cert_summary_selfsigned": "ADI: Uneko zirutagiria norberak sinatutakoa da. Web-nabigatzaileek bisitariak izutuko dituen mezu bat erakutsiko dute!",
|
||||||
"global_settings_setting_postfix_compatibility": "Postfixekin bateragarritasuna",
|
"global_settings_setting_postfix_compatibility": "Postfixekin bateragarritasuna",
|
||||||
"global_settings_setting_root_access_explain": "Linux sistemetan 'root' administratzaile gorena da. YunoHosten testuinguruan, zuzeneko 'root' SSH saioa ezgaituta dago defektuz, zerbitzariaren sare lokaletik ez bada. 'administrariak' taldeko kideek sudo komandoa erabili dezakete root bailitzan jarduteko terminalaren bidez. Hala ere lagungarri izan liteke root pasahitz (sendo) bat izatea sistema arazteko egoeraren batean administratzaile arruntek saiorik hasi ezin balute.",
|
"global_settings_setting_root_access_explain": "Linux sistemetan 'root' administratzaile gorena da. YunoHosten testuinguruan, zuzeneko 'root' SSH saioa ezgaituta dago defektuz, zerbitzariaren sare lokaletik ez bada. 'administratzaileak' taldeko kideek sudo komandoa erabili dezakete root bailitzan jarduteko terminalaren bidez. Hala ere lagungarri izan liteke root pasahitz (sendo) bat izatea sistema arazteko egoeraren batean administratzaile arruntek saiorik hasi ezin balute.",
|
||||||
"log_settings_reset": "Berrezarri ezarpenak",
|
"log_settings_reset": "Berrezarri ezarpenak",
|
||||||
"log_settings_reset_all": "Berrezarri ezarpen guztiak",
|
"log_settings_reset_all": "Berrezarri ezarpen guztiak",
|
||||||
"root_password_changed": "root pasahitza aldatu da",
|
"root_password_changed": "root pasahitza aldatu da",
|
||||||
|
@ -695,7 +695,7 @@
|
||||||
"diagnosis_using_stable_codename": "<cmd>apt</cmd> (sistemaren pakete kudeatzailea) 'stable' (egonkorra) izen kodea duten paketeak instalatzeko ezarrita dago une honetan, eta ez uneko Debianen bertsioaren (bullseye) izen kodea.",
|
"diagnosis_using_stable_codename": "<cmd>apt</cmd> (sistemaren pakete kudeatzailea) 'stable' (egonkorra) izen kodea duten paketeak instalatzeko ezarrita dago une honetan, eta ez uneko Debianen bertsioaren (bullseye) izen kodea.",
|
||||||
"diagnosis_using_yunohost_testing": "<cmd>apt</cmd> (sistemaren pakete kudeatzailea) YunoHosten muinerako 'testing' (proba) izen kodea duten paketeak instalatzeko ezarrita dago une honetan.",
|
"diagnosis_using_yunohost_testing": "<cmd>apt</cmd> (sistemaren pakete kudeatzailea) YunoHosten muinerako 'testing' (proba) izen kodea duten paketeak instalatzeko ezarrita dago une honetan.",
|
||||||
"diagnosis_using_yunohost_testing_details": "Ez dago arazorik zertan ari zaren baldin badakizu, baina arretaz irakurri oharrak YunoHosten eguneraketak instalatu baino lehen! 'testing' (proba) bertsioak ezgaitu nahi badituzu, kendu <cmd>testing</cmd> gakoa <cmd>/etc/apt/sources.list.d/yunohost.list</cmd> fitxategitik.",
|
"diagnosis_using_yunohost_testing_details": "Ez dago arazorik zertan ari zaren baldin badakizu, baina arretaz irakurri oharrak YunoHosten eguneraketak instalatu baino lehen! 'testing' (proba) bertsioak ezgaitu nahi badituzu, kendu <cmd>testing</cmd> gakoa <cmd>/etc/apt/sources.list.d/yunohost.list</cmd> fitxategitik.",
|
||||||
"global_settings_setting_smtp_allow_ipv6": "Baimendu IPv6",
|
"global_settings_setting_smtp_allow_ipv6": "Gaitu IPv6",
|
||||||
"global_settings_setting_smtp_relay_host": "SMTP errele-ostatatzailea",
|
"global_settings_setting_smtp_relay_host": "SMTP errele-ostatatzailea",
|
||||||
"domain_config_acme_eligible": "ACME hautagarritasuna",
|
"domain_config_acme_eligible": "ACME hautagarritasuna",
|
||||||
"domain_config_acme_eligible_explain": "Ez dirudi domeinu hau Let's Encrypt ziurtagirirako prest dagoenik. Egiaztatu DNS ezarpenak eta zerbitzariaren HTTP irisgarritasuna. <a href='#/diagnosis'>Diagnostikoen guneko</a> 'DNS erregistroak' eta 'Web' atalek zer dagoen gaizki ulertzen lagun zaitzakete.",
|
"domain_config_acme_eligible_explain": "Ez dirudi domeinu hau Let's Encrypt ziurtagirirako prest dagoenik. Egiaztatu DNS ezarpenak eta zerbitzariaren HTTP irisgarritasuna. <a href='#/diagnosis'>Diagnostikoen guneko</a> 'DNS erregistroak' eta 'Web' atalek zer dagoen gaizki ulertzen lagun zaitzakete.",
|
||||||
|
@ -720,12 +720,12 @@
|
||||||
"global_settings_setting_ssh_password_authentication": "Pasahitz bidezko autentifikazioa",
|
"global_settings_setting_ssh_password_authentication": "Pasahitz bidezko autentifikazioa",
|
||||||
"global_settings_setting_user_strength_help": "Betekizun hauek lehenbizikoz sortzerakoan edo pasahitza aldatzerakoan bete behar dira soilik",
|
"global_settings_setting_user_strength_help": "Betekizun hauek lehenbizikoz sortzerakoan edo pasahitza aldatzerakoan bete behar dira soilik",
|
||||||
"global_settings_setting_webadmin_allowlist": "Administrazio-atarira sartzeko baimendutako IPak",
|
"global_settings_setting_webadmin_allowlist": "Administrazio-atarira sartzeko baimendutako IPak",
|
||||||
"global_settings_setting_webadmin_allowlist_enabled": "Gaitu administrazio-ataria sartzeko baimendutako IPak",
|
"global_settings_setting_webadmin_allowlist_enabled": "Gaitu administrazio-gunera sartzeko baimendutako IPak",
|
||||||
"invalid_credentials": "Pasahitz edo erabiltzaile-izen baliogabea",
|
"invalid_credentials": "Pasahitz edo erabiltzaile-izen baliogabea",
|
||||||
"log_resource_snippet": "Baliabide bat eguneratzen / eskuratzen / eskuragarritasuna uzten",
|
"log_resource_snippet": "Baliabide bat eguneratzen / eskuratzen / eskuragarritasuna uzten",
|
||||||
"log_settings_set": "Aplikatu ezarpenak",
|
"log_settings_set": "Aplikatu ezarpenak",
|
||||||
"migration_description_0025_global_settings_to_configpanel": "Migratu ezarpen globalen nomenklatura zaharra izendegi berri eta modernora",
|
"migration_description_0025_global_settings_to_configpanel": "Migratu ezarpen globalen nomenklatura zaharra izendegi berri eta modernora",
|
||||||
"migration_description_0026_new_admins_group": "Migratu 'administrari bat baino gehiago' sistema berrira",
|
"migration_description_0026_new_admins_group": "Migratu 'administratzaile bat baino gehiago' sistema berrira",
|
||||||
"password_confirmation_not_the_same": "Pasahitzak ez datoz bat",
|
"password_confirmation_not_the_same": "Pasahitzak ez datoz bat",
|
||||||
"password_too_long": "Aukeratu 127 karaktere baino laburragoa den pasahitz bat",
|
"password_too_long": "Aukeratu 127 karaktere baino laburragoa den pasahitz bat",
|
||||||
"diagnosis_using_stable_codename_details": "Ostatatzaileak zerbait oker ezarri duenean gertatu ohi da hau. Arriskutsua da, Debianen datorren bertsioa 'estable' (egonkorra) bilakatzen denean, <cmd>apt</cmd>-k sistemaren pakete guztiak bertsio-berritzen saiatuko da, beharrezko migrazio-prozedurarik burutu gabe. Debianen gordailuan apt iturria editatzen konpontzea da gomendioa, <cmd>stable</cmd> gakoa <cmd>bullseye</cmd> gakoarekin ordezkatuz. Ezarpen-fitxategia <cmd>/etc/apt/sources.list</cmd> izan beharko litzateke, edo <cmd>/etc/apt/sources.list.d/</cmd> direktorioko fitxategiren bat.",
|
"diagnosis_using_stable_codename_details": "Ostatatzaileak zerbait oker ezarri duenean gertatu ohi da hau. Arriskutsua da, Debianen datorren bertsioa 'estable' (egonkorra) bilakatzen denean, <cmd>apt</cmd>-k sistemaren pakete guztiak bertsio-berritzen saiatuko da, beharrezko migrazio-prozedurarik burutu gabe. Debianen gordailuan apt iturria editatzen konpontzea da gomendioa, <cmd>stable</cmd> gakoa <cmd>bullseye</cmd> gakoarekin ordezkatuz. Ezarpen-fitxategia <cmd>/etc/apt/sources.list</cmd> izan beharko litzateke, edo <cmd>/etc/apt/sources.list.d/</cmd> direktorioko fitxategiren bat.",
|
||||||
|
@ -739,7 +739,7 @@
|
||||||
"app_resource_failed": "{app} aplikaziorako baliabideen eguneraketak / prestaketak / askapenak huts egin du: {error}",
|
"app_resource_failed": "{app} aplikaziorako baliabideen eguneraketak / prestaketak / askapenak huts egin du: {error}",
|
||||||
"app_not_enough_disk": "Aplikazio honek {required} espazio libre behar ditu.",
|
"app_not_enough_disk": "Aplikazio honek {required} espazio libre behar ditu.",
|
||||||
"app_yunohost_version_not_supported": "Aplikazio honek YunoHost >= {required} behar du baina unean instalatutako bertsioa {current} da",
|
"app_yunohost_version_not_supported": "Aplikazio honek YunoHost >= {required} behar du baina unean instalatutako bertsioa {current} da",
|
||||||
"global_settings_setting_passwordless_sudo": "Baimendu administrariek 'sudo' erabiltzea pasahitzak berriro idatzi beharrik gabe",
|
"global_settings_setting_passwordless_sudo": "Baimendu administratzaileek 'sudo' erabiltzea pasahitzak berriro idatzi beharrik gabe",
|
||||||
"global_settings_setting_portal_theme": "Atariko gaia",
|
"global_settings_setting_portal_theme": "Atariko gaia",
|
||||||
"global_settings_setting_portal_theme_help": "Atariko gai propioak sortzeari buruzko informazio gehiago: https://yunohost.org/theming",
|
"global_settings_setting_portal_theme_help": "Atariko gai propioak sortzeari buruzko informazio gehiago: https://yunohost.org/theming",
|
||||||
"invalid_shell": "Shell baliogabea: {shell}",
|
"invalid_shell": "Shell baliogabea: {shell}",
|
||||||
|
@ -765,7 +765,7 @@
|
||||||
"group_user_add": "'{user}' erabiltzailea '{group}' taldera gehituko da",
|
"group_user_add": "'{user}' erabiltzailea '{group}' taldera gehituko da",
|
||||||
"ask_dyndns_recovery_password_explain": "Aukeratu DynDNS domeinurako berreskuratze-pasahitza, etorkizunean berrezarri beharko bazenu.",
|
"ask_dyndns_recovery_password_explain": "Aukeratu DynDNS domeinurako berreskuratze-pasahitza, etorkizunean berrezarri beharko bazenu.",
|
||||||
"ask_dyndns_recovery_password_explain_during_unsubscribe": "Sartu DynDNS domeinuaren berreskuratze-pasahitza.",
|
"ask_dyndns_recovery_password_explain_during_unsubscribe": "Sartu DynDNS domeinuaren berreskuratze-pasahitza.",
|
||||||
"dyndns_no_recovery_password": "Ez da berreskuratze-pasahitzik zehaztu! Domeinuaren gaineko kontrola galduz gero, YunoHost taldeko administrariarekin jarri beharko zara harremanetan!",
|
"dyndns_no_recovery_password": "Ez da berreskuratze-pasahitzik zehaztu! Domeinuaren gaineko kontrola galduz gero, YunoHost taldeko administratzailearekin jarri beharko zara harremanetan!",
|
||||||
"ask_dyndns_recovery_password": "DynDNS berreskuratze-pasahitza",
|
"ask_dyndns_recovery_password": "DynDNS berreskuratze-pasahitza",
|
||||||
"dyndns_subscribed": "DynDNS domeinua harpidetu da",
|
"dyndns_subscribed": "DynDNS domeinua harpidetu da",
|
||||||
"dyndns_subscribe_failed": "Ezin izan da DynDNS domeinua harpidetu: {error}",
|
"dyndns_subscribe_failed": "Ezin izan da DynDNS domeinua harpidetu: {error}",
|
||||||
|
@ -781,5 +781,33 @@
|
||||||
"dyndns_set_recovery_password_invalid_password": "Berreskuratze-pasahitza ezartzeak huts egin du: pasahitza ez da nahikoa sendoa",
|
"dyndns_set_recovery_password_invalid_password": "Berreskuratze-pasahitza ezartzeak huts egin du: pasahitza ez da nahikoa sendoa",
|
||||||
"dyndns_set_recovery_password_failed": "Berreskuratze-pasahitza ezartzeak huts egin du: {error}",
|
"dyndns_set_recovery_password_failed": "Berreskuratze-pasahitza ezartzeak huts egin du: {error}",
|
||||||
"dyndns_set_recovery_password_success": "Berreskuratze-pasahitza ezarri da!",
|
"dyndns_set_recovery_password_success": "Berreskuratze-pasahitza ezarri da!",
|
||||||
"global_settings_setting_ssh_port_help": "1024 baino ataka txikiago bat izan beharko litzateke, zerbitzu ez-administratzaileek urruneko makinan usurpazio-saiorik egin ez dezaten. Lehendik ere erabiltzen ari diren atakak ere ekidin beharko zenituzke, 80 edo 443 kasu."
|
"global_settings_setting_ssh_port_help": "1024 baino ataka txikiago bat izan beharko litzateke, zerbitzu ez-administratzaileek urruneko makinan usurpazio-saiorik egin ez dezaten. Lehendik ere erabiltzen ari diren atakak ere ekidin beharko zenituzke, 80 edo 443 kasu.",
|
||||||
|
"migration_0027_start": "Bookworm-erako migrazioa abiarazten…",
|
||||||
|
"migration_0027_still_on_bullseye_after_main_upgrade": "Zerbaitek kale egin du bertsio-berritze nagusian; sistemak oraindik Debian Bullseye darabilela dirudi.",
|
||||||
|
"migration_0027_general_warning": "Migrazioa tentuz ibiltzeko prozedura da. YunoHosten taldeak ahal izan duen guztia egin du berrikusi eta probatzeko, baina hala ere sistemaren atalak edo aplikazioak honda litzake.\n\nBeraz, gomendagarria da:\n - Datu edo aplikazio garrantzitsuen babeskopia egitea. Informazio gehiagorako: https://yunohost.org/backup;\n - Ez izan presarik migrazioa abiaraztean: internet konexioaren eta hardwarearen arabera, litekeena da ordu apur batzuk ere behar izatea guztia dagokion bezala bertsio-berritzeko.",
|
||||||
|
"migration_description_0027_migrate_to_bookworm": "Bertsio-berritu sistema Debian Bookworm eta YunoHost 12-ra",
|
||||||
|
"migration_0027_system_not_fully_up_to_date": "Sistema ez dago erabat egunean. Egizu eguneraketa arrunt bat Bookworm-erako migrazioa abiarazi baino lehen.",
|
||||||
|
"diagnosis_ignore_filter_added": "{category} atalaren diagnostikorako iragazkia gehitu da",
|
||||||
|
"migration_0027_problematic_apps_warning": "Kontuan izan ziur asko gatazkatsuak izango diren ondorengo aplikazioak aurkitu direla. Badirudi ez zirela YunoHost aplikazioen katalogotik instalatu, edo ez daude 'badabiltza' bezala etiketatuak. Ondorioz, ezin da bermatu eguneratu ondoren funtzionatzen jarraituko dutenik: {problematic_apps}",
|
||||||
|
"diagnosis_ignore_missing_criteria": "Gutxienez irizpide bat gehitu behar duzu atalaren diagnostikoak kontuan har ez dezan",
|
||||||
|
"migration_0027_not_bullseye": "Zerbitzariak darabilen Debian bertsioa ez da Bullseye! Dagoeneko Bullseye -> Bookworm migrazioa exekutatu baduzu, errore honek migrazioa erabat arrakastatsua izan ez zela esan nahi du (bestela YunoHostek amaitutzat markatuko luke). Komenigarria izango litzateke, laguntza taldearekin batera, zer gertatu zen aztertzea. Horretarako migrazioaren erregistro **osoa** beharko duzue, Tresnak > Erregistroak atalean eskuragarri dagoena.",
|
||||||
|
"diagnosis_ignore_criteria_error": "Irizpideek forma hau izan behar dute: gakoa=balorea (adib. domain=yolo.test)",
|
||||||
|
"diagnosis_ignore_already_filtered": "(Badago lehendik ere irizpide horiek dituen {category} atalaren diagnostikorako iragazkia)",
|
||||||
|
"diagnosis_ignore_filter_removed": "{category} atalaren diagnostikorako iragazkia kendu da",
|
||||||
|
"diagnosis_ignore_no_filter_found": "(Ez dago irizpide horiek dituen {category} atalaren diagnostikorako iragazkirik)",
|
||||||
|
"diagnosis_ignore_no_issue_found": "Ez da arazorik aurkitu emandako irizpideekin.",
|
||||||
|
"migration_0027_delayed_api_restart": "YunoHosten APIa 15 segundu barru berrabiaraziko da automatikoki. Litekeena da tarte batez erabilgarri egoteari uztea eta ondoren berriro hasi beharko duzu saioa.",
|
||||||
|
"migration_0027_main_upgrade": "Bertsio-berritze nagusia abiarazten…",
|
||||||
|
"migration_0027_cleaning_up": "Erabilgarri izateari utzi dioten katxe eta paketeak garbitzen…",
|
||||||
|
"migration_0027_yunohost_upgrade": "YunoHosten muineko bertsio-berriztea abiarazten…",
|
||||||
|
"migration_0027_patch_yunohost_conflicts": "Arazo gatazkatsu bati adabakia jartzen…",
|
||||||
|
"migration_0027_modified_files": "Ondorengo fitxategiak eskuz moldatu direla antzeman da eta litekeena da bertsio-berritzeak gainean idaztea: {manually_modified_files}",
|
||||||
|
"migration_0027_not_enough_free_space": "/var/-en erabilgarri dagoen espazioa oso txikia da! Gutxienez GB 1 izan beharko zenuke erabilgarri migrazioari ekiteko.",
|
||||||
|
"migration_0027_patching_sources_list": "sources.lists fitxategia petatxatzen…",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted": "Baimendutako posta elektronikoen MXren SMTP babeskopia",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains": "Bigarren mailako MX gisa jarduteko domeinuak",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains_help": "Zerbitzari honek zerrendan agertzen den domeinurako *bigarren mailako* MX domeinu gisa jardun dezake. Domeinurako lehenetsitako MX lortu ezin denean (adibidez, itzalaldi baten ondorioz), mezuak bigarren zerbitzari horretara bidaliko dira —gehienez 20 egunez mantenduko dituena— eta berriro eskuragarri dagoenean benetako helburura helarazten saiatuko da. Hainbat domeinu zehaztu daitezke, komaz bereizita.",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted_help": "Bigarren mailako MX gisa jarduten duenean, baimendutako hartzaileen posta elektronikoko helbideen zerrenda zehatza eman beharko da (bestela, mezuak ukatu eta baztertuko dira). Hainbat sarrera eman daitezke, komaz bereizita.",
|
||||||
|
"diagnosis_rfkill_wifi_details": "Ohartarazpena komando askotan ageri da, aplikazio batzuk hautsiz. Herrialdearen kodea zehaztuz konpon daiteke <code>sudo raspi-config</code> komandoaren bidez. Hau da errorea:<br>{rfkill_wifi_error}",
|
||||||
|
"diagnosis_rfkill_wifi": "Wi-Fi txartela ezgaituta dago eta sistemaren ohartarazpen batek aplikazioen instalazioak eragotzi ditzake"
|
||||||
}
|
}
|
||||||
|
|
|
@ -781,5 +781,33 @@
|
||||||
"log_dyndns_unsubscribe": "Se désabonner d'un sous-domaine YunoHost '{}'",
|
"log_dyndns_unsubscribe": "Se désabonner d'un sous-domaine YunoHost '{}'",
|
||||||
"dyndns_too_many_requests": "Le service dyndns de YunoHost a reçu trop de requêtes/demandes de votre part, attendez environ 1 heure avant de réessayer.",
|
"dyndns_too_many_requests": "Le service dyndns de YunoHost a reçu trop de requêtes/demandes de votre part, attendez environ 1 heure avant de réessayer.",
|
||||||
"ask_dyndns_recovery_password_explain_unavailable": "Ce domaine DynDNS est déjà enregistré. Si vous êtes la personne qui a enregistré ce domaine lors de sa création, vous pouvez entrer le mot de passe de récupération pour récupérer ce domaine.",
|
"ask_dyndns_recovery_password_explain_unavailable": "Ce domaine DynDNS est déjà enregistré. Si vous êtes la personne qui a enregistré ce domaine lors de sa création, vous pouvez entrer le mot de passe de récupération pour récupérer ce domaine.",
|
||||||
"global_settings_setting_ssh_port_help": "Il est préférable d'utiliser un port inférieur à 1024 pour éviter les tentatives d'usurpation par des services non administrateurs sur la machine distante. Vous devez également éviter d'utiliser un port déjà utilisé tel que le 80 ou le 443."
|
"global_settings_setting_ssh_port_help": "Il est préférable d'utiliser un port inférieur à 1024 pour éviter les tentatives d'usurpation par des services non administrateurs sur la machine distante. Vous devez également éviter d'utiliser un port déjà utilisé tel que le 80 ou le 443.",
|
||||||
|
"diagnosis_rfkill_wifi": "La carte Wi-Fi est désactivée et un avertissement du système pourrait empêcher d'installer des applications",
|
||||||
|
"diagnosis_rfkill_wifi_details": "Cet avertissement se glisse dans beaucoup de retours de commandes, cassant certaines applications. Il s'agit généralement de spécifier votre code pays avec la commande <code>sudo raspi-config</code>. Voici l'erreur:<br>{rfkill_wifi_error}",
|
||||||
|
"diagnosis_ignore_already_filtered": "(Il y a déjà un filtre de diagnostic {category} qui correspond à ces critères)",
|
||||||
|
"diagnosis_ignore_no_filter_found": "(Il n'y pas de filtre de diagnostic pour la catégorie {category} qui correspond à ces critères)",
|
||||||
|
"diagnosis_ignore_filter_added": "Filtre de diagnostic pour {category} ajouté",
|
||||||
|
"diagnosis_ignore_filter_removed": "Filtre de diagnostic pour {category} supprimé",
|
||||||
|
"diagnosis_ignore_missing_criteria": "Vous devez fournir au moins un critère qui est une catégorie de diagnostic à ignorer",
|
||||||
|
"diagnosis_ignore_criteria_error": "Les critères doivent être sous la forme de clé=valeur (ex. domain=yolo.test)",
|
||||||
|
"diagnosis_ignore_no_issue_found": "Aucun problème correspondant au critère donné n'a été trouvé.",
|
||||||
|
"migration_description_0027_migrate_to_bookworm": "Mettre à jour le système vers Debian Bookworm et YunoHost 12",
|
||||||
|
"migration_0027_delayed_api_restart": "L'API de YunoHost sera automatiquement redémarrée dans 15 secondes. Il se peut qu'elle soit indisponible pendant quelques secondes, après quoi vous devrez vous connecter à nouveau.",
|
||||||
|
"migration_0027_general_warning": "Veuillez noter que cette migration est une opération délicate. L'équipe de YunoHost a fait de son mieux pour l'examiner et la tester, mais la migration peut encore casser des parties du système ou de ses applications.\n\nPar conséquent, il est recommandé :\n - d'effectuer une sauvegarde de toutes les données ou applications critiques. Plus d'informations sur https://yunohost.org/backup ;\n - de faire preuve de patience après avoir lancé la migration : en fonction de votre connexion Internet et de votre matériel, la mise à niveau peut prendre quelques heures pour s'effectuer correctement.",
|
||||||
|
"migration_0027_not_bullseye": "La distribution Debian actuelle n'est pas Bullseye ! Si vous avez déjà effectué la migration Bullseye -> Bookworm, cette erreur est symptomatique du fait que la procédure de migration n'a pas réussi à 100 % (sinon YunoHost l'aurait marquée comme terminée). Il est recommandé de chercher ce qui s'est passé avec l'équipe de support, qui aura besoin du journal **complet** de la migration, qui peut être trouvé dans Outils > Journaux dans la webadmin.",
|
||||||
|
"migration_0027_cleaning_up": "Nettoyage du cache et des paquets qui ne sont plus utiles…",
|
||||||
|
"migration_0027_main_upgrade": "Démarrage de la mise à niveau du système…",
|
||||||
|
"migration_0027_modified_files": "Veuillez noter que les fichiers suivants ont été modifiés manuellement et pourraient être écrasés après la mise à niveau : {manually_modified_files}",
|
||||||
|
"migration_0027_not_enough_free_space": "L'espace libre est plutôt faible dans /var/ ! Vous devez disposer d'au moins 1 Go d'espace libre pour effectuer cette migration.",
|
||||||
|
"migration_0027_patch_yunohost_conflicts": "Application d'un correctif pour résoudre le problème de conflit…",
|
||||||
|
"migration_0027_patching_sources_list": "Correction du fichier sources.lists…",
|
||||||
|
"migration_0027_problematic_apps_warning": "Veuillez noter que des applications installées susceptibles de poser problème ont été détectées. Il semble qu'elles n'aient pas été installées à partir du catalogue d'applications de YunoHost, ou bien qu'elles ne soient pas marquées comme 'fonctionnelles'. Par conséquent, il ne peut pas être garanti qu'elles continueront à fonctionner après la mise à jour : {problematic_apps}",
|
||||||
|
"migration_0027_start": "Démarrage de la migration vers Bookworm…",
|
||||||
|
"migration_0027_still_on_bullseye_after_main_upgrade": "Quelque chose s'est mal passé lors de la mise à jour du système, il semble que celui-ci soit toujours sous Debian Bullseye.",
|
||||||
|
"migration_0027_system_not_fully_up_to_date": "Votre système n'est pas complètement à jour. Veuillez effectuer une mise à jour classique avant de procéder à la migration vers Bookworm.",
|
||||||
|
"migration_0027_yunohost_upgrade": "Démarrage de la mise à jour du cœur de YunoHost…",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains": "Domaines à utiliser comme MX secondaire pour",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted": "Sauvegarde SMTP des emails sur liste blanche du MX",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted_help": "Dans le cas d'un MX secondaire, la liste exhaustive des adresses électroniques des destinataires autorisés doit être fournie (sinon les courriers seront refusés et rejetés). Plusieurs entrées peuvent être fournies, séparées par des virgules.",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains_help": "Autoriser ce serveur à agir en tant que domaine MX *secondaire* de secours pour le domaine listé. Cela signifie que si le MX principal pour le domaine n'est pas accessible (par exemple à cause d'une panne), les courriers électroniques seront quand même envoyés à ce serveur, qui les conservera pendant un maximum de 20 jours et essaiera de les relayer vers la destination réelle une fois qu'il sera rétabli. Plusieurs domaines peuvent être fournis, séparés par des virgules."
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
"apps_catalog_failed_to_download": "Non se puido descargar o catálogo de apps {apps_catalog}: {error}",
|
"apps_catalog_failed_to_download": "Non se puido descargar o catálogo de apps {apps_catalog}: {error}",
|
||||||
"apps_catalog_updating": "Actualizando o catálogo de aplicacións…",
|
"apps_catalog_updating": "Actualizando o catálogo de aplicacións…",
|
||||||
"apps_catalog_init_success": "Sistema do catálogo de apps iniciado!",
|
"apps_catalog_init_success": "Sistema do catálogo de apps iniciado!",
|
||||||
"apps_already_up_to_date": "Xa tes tódalas apps ao día",
|
"apps_already_up_to_date": "Xa tes todas as apps ao día",
|
||||||
"app_packaging_format_not_supported": "Esta app non se pode instalar porque o formato de empaquetado non está soportado pola túa versión de YunoHost. Deberías considerar actualizar o teu sistema.",
|
"app_packaging_format_not_supported": "Esta app non se pode instalar porque o formato de empaquetado non está soportado pola túa versión de YunoHost. Deberías considerar actualizar o teu sistema.",
|
||||||
"app_upgraded": "{app} actualizadas",
|
"app_upgraded": "{app} actualizadas",
|
||||||
"app_upgrade_some_app_failed": "Algunhas apps non se puideron actualizar",
|
"app_upgrade_some_app_failed": "Algunhas apps non se puideron actualizar",
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
"backup_permission": "Permiso de copia para {app}",
|
"backup_permission": "Permiso de copia para {app}",
|
||||||
"backup_output_symlink_dir_broken": "O directorio de arquivo '{path}' é unha ligazón simbólica rota. Pode ser que esqueceses re/montar ou conectar o medio de almacenaxe ao que apunta.",
|
"backup_output_symlink_dir_broken": "O directorio de arquivo '{path}' é unha ligazón simbólica rota. Pode ser que esqueceses re/montar ou conectar o medio de almacenaxe ao que apunta.",
|
||||||
"backup_output_directory_required": "Debes proporcionar un directorio de saída para a copia",
|
"backup_output_directory_required": "Debes proporcionar un directorio de saída para a copia",
|
||||||
"backup_output_directory_not_empty": "Debes elexir un directorio de saída baleiro",
|
"backup_output_directory_not_empty": "Debes elixir un directorio de saída baleiro",
|
||||||
"backup_output_directory_forbidden": "Elixe un directorio de saída diferente. As copias non poden crearse en /bin, /boot, /dev, /etc, /lib, /root, /sbin, /sys, /usr, /var ou subcartafoles de /home/yunohost.backup/archives",
|
"backup_output_directory_forbidden": "Elixe un directorio de saída diferente. As copias non poden crearse en /bin, /boot, /dev, /etc, /lib, /root, /sbin, /sys, /usr, /var ou subcartafoles de /home/yunohost.backup/archives",
|
||||||
"backup_nothings_done": "Nada que gardar",
|
"backup_nothings_done": "Nada que gardar",
|
||||||
"backup_no_uncompress_archive_dir": "Non hai tal directorio do arquivo descomprimido",
|
"backup_no_uncompress_archive_dir": "Non hai tal directorio do arquivo descomprimido",
|
||||||
|
@ -317,7 +317,7 @@
|
||||||
"group_cannot_be_deleted": "O grupo {group} non se pode eliminar manualmente.",
|
"group_cannot_be_deleted": "O grupo {group} non se pode eliminar manualmente.",
|
||||||
"group_cannot_edit_primary_group": "O grupo '{group}' non se pode editar manualmente. É o grupo primario que contén só a unha usuaria concreta.",
|
"group_cannot_edit_primary_group": "O grupo '{group}' non se pode editar manualmente. É o grupo primario que contén só a unha usuaria concreta.",
|
||||||
"group_cannot_edit_visitors": "O grupo 'visitors' non se pode editar manualmente. É un grupo especial que representa a tódas visitantes anónimas",
|
"group_cannot_edit_visitors": "O grupo 'visitors' non se pode editar manualmente. É un grupo especial que representa a tódas visitantes anónimas",
|
||||||
"group_cannot_edit_all_users": "O grupo 'all_users' non se pode editar manualmente. É un grupo especial que contén tódalas usuarias rexistradas en YunoHost",
|
"group_cannot_edit_all_users": "O grupo 'all_users' non se pode editar manualmente. É un grupo especial que contén todas as usuarias rexistradas en YunoHost",
|
||||||
"disk_space_not_sufficient_update": "Non hai espazo suficiente no disco para actualizar esta aplicación",
|
"disk_space_not_sufficient_update": "Non hai espazo suficiente no disco para actualizar esta aplicación",
|
||||||
"disk_space_not_sufficient_install": "Non queda espazo suficiente no disco para instalar esta aplicación",
|
"disk_space_not_sufficient_install": "Non queda espazo suficiente no disco para instalar esta aplicación",
|
||||||
"log_help_to_get_log": "Para ver o rexistro completo da operación '{desc}', usa o comando 'yunohost log show {name}'",
|
"log_help_to_get_log": "Para ver o rexistro completo da operación '{desc}', usa o comando 'yunohost log show {name}'",
|
||||||
|
@ -447,8 +447,8 @@
|
||||||
"permission_not_found": "Non se atopa o permiso '{permission}'",
|
"permission_not_found": "Non se atopa o permiso '{permission}'",
|
||||||
"permission_deletion_failed": "Non se puido eliminar o permiso '{permission}': {error}",
|
"permission_deletion_failed": "Non se puido eliminar o permiso '{permission}': {error}",
|
||||||
"permission_deleted": "O permiso '{permission}' foi eliminado",
|
"permission_deleted": "O permiso '{permission}' foi eliminado",
|
||||||
"permission_cant_add_to_all_users": "O permiso {permission} non pode ser concecido a tódalas usuarias.",
|
"permission_cant_add_to_all_users": "O permiso {permission} non se pode conceder a todas as usuarias.",
|
||||||
"permission_currently_allowed_for_all_users": "Este permiso está concedido actualmente a tódalas usuarias ademáis de a outros grupos. Probablemente queiras ben eliminar o permiso 'all_users' ou ben eliminar os outros grupos que teñen permiso.",
|
"permission_currently_allowed_for_all_users": "Este permiso está concedido actualmente para todas as usuarias ademáis de a outros grupos. Probablemente queiras ben eliminar o permiso 'all_users' ou ben eliminar os outros grupos que teñen permiso.",
|
||||||
"restore_failed": "Non se puido restablecer o sistema",
|
"restore_failed": "Non se puido restablecer o sistema",
|
||||||
"restore_extracting": "A extraer os ficheiros necesarios desde o arquivo…",
|
"restore_extracting": "A extraer os ficheiros necesarios desde o arquivo…",
|
||||||
"restore_confirm_yunohost_installed": "Tes a certeza de querer restablecer un sistema xa instalado? [{answers}]",
|
"restore_confirm_yunohost_installed": "Tes a certeza de querer restablecer un sistema xa instalado? [{answers}]",
|
||||||
|
@ -553,7 +553,7 @@
|
||||||
"service_removed": "Eliminado o servizo '{service}'",
|
"service_removed": "Eliminado o servizo '{service}'",
|
||||||
"service_remove_failed": "Non se eliminou o servizo '{service}'",
|
"service_remove_failed": "Non se eliminou o servizo '{service}'",
|
||||||
"service_enabled": "O servizo '{service}' vai ser iniciado automáticamente no inicio do sistema.",
|
"service_enabled": "O servizo '{service}' vai ser iniciado automáticamente no inicio do sistema.",
|
||||||
"diagnosis_apps_allgood": "Tódalas apps instaladas respectan as prácticas básicas de empaquetado",
|
"diagnosis_apps_allgood": "Todas as apps instaladas respectan as prácticas básicas de empaquetado",
|
||||||
"diagnosis_apps_bad_quality": "Esta aplicación está actualmente marcada como estragada no catálogo de aplicacións de YunoHost. Podería ser un problema temporal mentras as mantedoras intentan arranxar o problema. Ata ese momento a actualización desta app está desactivada.",
|
"diagnosis_apps_bad_quality": "Esta aplicación está actualmente marcada como estragada no catálogo de aplicacións de YunoHost. Podería ser un problema temporal mentras as mantedoras intentan arranxar o problema. Ata ese momento a actualización desta app está desactivada.",
|
||||||
"log_user_import": "Importar usuarias",
|
"log_user_import": "Importar usuarias",
|
||||||
"user_import_failed": "A operación de importación de usuarias fracasou",
|
"user_import_failed": "A operación de importación de usuarias fracasou",
|
||||||
|
@ -664,7 +664,7 @@
|
||||||
"migration_0024_rebuild_python_venv_in_progress": "Intentando reconstruir o Python virtualenv para `{app}`",
|
"migration_0024_rebuild_python_venv_in_progress": "Intentando reconstruir o Python virtualenv para `{app}`",
|
||||||
"migration_description_0024_rebuild_python_venv": "Reparar app Python após a migración a bullseye",
|
"migration_description_0024_rebuild_python_venv": "Reparar app Python após a migración a bullseye",
|
||||||
"migration_0024_rebuild_python_venv_failed": "Fallou a reconstrución de Python virtualenv para {app}. A app podería non funcionar mentras non se resolve. Deberías intentar arranxar a situación forzando a actualización desta app usando `yunohost app upgrade --force {app}`.",
|
"migration_0024_rebuild_python_venv_failed": "Fallou a reconstrución de Python virtualenv para {app}. A app podería non funcionar mentras non se resolve. Deberías intentar arranxar a situación forzando a actualización desta app usando `yunohost app upgrade --force {app}`.",
|
||||||
"migration_0021_not_buster2": "A distribución actual Debian non é Buster! Se xa realizaches a migración Buster->Bullseye entón este erro indica que o proceso de migración non se realizou de xeito correcto ao 100% (se non YunoHost debería telo marcado como completado). É recomendable comprobar xunto co equipo de axuda o que aconteceu, necesitarán o rexistro **completo** da `migración`, que podes atopar na webadmin en Ferramentas > Rexistros.",
|
"migration_0021_not_buster2": "A distribución actual Debian non é Buster! Se xa realizaches a migración Buster -> Bullseye entón este erro indica que o proceso de migración non se realizou de xeito correcto ao 100% (se non YunoHost debería telo marcado como completado). É recomendable comprobar xunto co equipo de axuda o que aconteceu, necesitarán o rexistro **completo** da migración, que podes atopar na webadmin en Ferramentas > Rexistros.",
|
||||||
"global_settings_setting_admin_strength_help": "Estos requerimentos só se esixen ao inicializar ou cambiar o contrasinal",
|
"global_settings_setting_admin_strength_help": "Estos requerimentos só se esixen ao inicializar ou cambiar o contrasinal",
|
||||||
"global_settings_setting_root_access_explain": "En sistemas Linux, 'root' é a administradora absoluta. No contexto YunoHost, o acceso SSH de 'root' está desactivado por defecto - excepto na rede local do servidor. Os compoñentes do grupo 'admins' poden utilizar o comando sudo para actuar como root desde a liña de comandos. É conveniente ter un contrasinal (forte) para root para xestionar o sistema por se as persoas administradoras perden o acceso por algún motivo.",
|
"global_settings_setting_root_access_explain": "En sistemas Linux, 'root' é a administradora absoluta. No contexto YunoHost, o acceso SSH de 'root' está desactivado por defecto - excepto na rede local do servidor. Os compoñentes do grupo 'admins' poden utilizar o comando sudo para actuar como root desde a liña de comandos. É conveniente ter un contrasinal (forte) para root para xestionar o sistema por se as persoas administradoras perden o acceso por algún motivo.",
|
||||||
"migration_description_0025_global_settings_to_configpanel": "Migrar o nome antigo dos axustes globais aos novos nomes modernos",
|
"migration_description_0025_global_settings_to_configpanel": "Migrar o nome antigo dos axustes globais aos novos nomes modernos",
|
||||||
|
@ -692,7 +692,7 @@
|
||||||
"log_settings_reset_all": "Restablecer todos os axustes",
|
"log_settings_reset_all": "Restablecer todos os axustes",
|
||||||
"log_settings_set": "Aplicar axustes",
|
"log_settings_set": "Aplicar axustes",
|
||||||
"admins": "Admins",
|
"admins": "Admins",
|
||||||
"all_users": "Tódalas usuarias de YunoHost",
|
"all_users": "Usuarias de YunoHost",
|
||||||
"app_action_failed": "Fallou a execución da acción {action} da app {app}",
|
"app_action_failed": "Fallou a execución da acción {action} da app {app}",
|
||||||
"app_manifest_install_ask_init_admin_permission": "Quen debería ter acceso de administración a esta app? (Pode cambiarse despois)",
|
"app_manifest_install_ask_init_admin_permission": "Quen debería ter acceso de administración a esta app? (Pode cambiarse despois)",
|
||||||
"app_manifest_install_ask_init_main_permission": "Quen debería ter acceso a esta app? (Pode cambiarse despois)",
|
"app_manifest_install_ask_init_main_permission": "Quen debería ter acceso a esta app? (Pode cambiarse despois)",
|
||||||
|
@ -781,5 +781,33 @@
|
||||||
"log_dyndns_unsubscribe": "Retirar subscrición para o subdominio YunoHost '{}'",
|
"log_dyndns_unsubscribe": "Retirar subscrición para o subdominio YunoHost '{}'",
|
||||||
"ask_dyndns_recovery_password_explain_unavailable": "Este dominio DynDNS xa está rexistrado. Se es a persoa que o rexistrou orixinalmente, podes escribir o código de recuperación para reclamar o dominio.",
|
"ask_dyndns_recovery_password_explain_unavailable": "Este dominio DynDNS xa está rexistrado. Se es a persoa que o rexistrou orixinalmente, podes escribir o código de recuperación para reclamar o dominio.",
|
||||||
"dyndns_too_many_requests": "O servicio dyndns de YunoHost recibeu demasiadas peticións do teu sistema, agarda 1 hora e volve intentalo.",
|
"dyndns_too_many_requests": "O servicio dyndns de YunoHost recibeu demasiadas peticións do teu sistema, agarda 1 hora e volve intentalo.",
|
||||||
"global_settings_setting_ssh_port_help": "É recomendable un porto inferior a 1024 para evitar os intentos de apropiación por parte de servizos de non-administración na máquina remota. Tamén deberías evitar elexir un porto que xa está sendo utilizado, como 80 ou 443."
|
"global_settings_setting_ssh_port_help": "É recomendable un porto inferior a 1024 para evitar os intentos de apropiación por parte de servizos de non-administración na máquina remota. Tamén deberías evitar elixir un porto que xa está sendo utilizado, como 80 ou 443.",
|
||||||
|
"diagnosis_ignore_criteria_error": "Os criterios deben ter o formato key=value (ex. domain=yolo.test)",
|
||||||
|
"diagnosis_ignore_already_filtered": "(Xa existe un filtro de diagnóstico de {category} con estes criterios)",
|
||||||
|
"diagnosis_ignore_filter_removed": "Eliminouse o filtro do diagnóstico para {category}",
|
||||||
|
"diagnosis_ignore_no_filter_found": "(Non hai tal filtro do diagnóstico de {category} con este criterio a eliminar)",
|
||||||
|
"diagnosis_ignore_no_issue_found": "Non se atoparon incidencias para o criterio establecido.",
|
||||||
|
"diagnosis_ignore_filter_added": "Engadiuse o filtro do diagnóstico para {category}",
|
||||||
|
"diagnosis_ignore_missing_criteria": "Deberías proporcionar cando menos un criterio que a categoría de diagnóstico omitirá",
|
||||||
|
"migration_0027_start": "A iniciar a migración a Bookworm…",
|
||||||
|
"migration_0027_still_on_bullseye_after_main_upgrade": "Algo fallou durante a actualización principal, o sistema parece que aínda está en Debian Bullseye.",
|
||||||
|
"migration_0027_patching_sources_list": "A configurar o ficheiro sources.list…",
|
||||||
|
"migration_0027_general_warning": "Ten en conta que a migración é unha operación comprometida. O equipo de YunoHost intentou deseñala o mellor posible e probala, aínda así a migración podería estragar partes do sistema ou as aplicacións.\n\nAsí, é recomendable:\n - Facer unha copia de apoio dos datos críticos ou aplicacións. Máis info en https://yunohost.org/backup;\n - Ter pacencia unha vez iniciada a migración: en función da túa conexión a Internet e hardware podería levarlle varias horas completar todo o procedemento.",
|
||||||
|
"migration_0027_yunohost_upgrade": "A iniciar a actualización do núcleo de YunoHost…",
|
||||||
|
"migration_0027_not_bullseye": "A distribución Debian actual non é Bullseye! Se xa realizaches a migración Bullseye -> Bookworm este erro é síntoma de que o procedemento de migración non foi exitoso ao 100% (doutro xeito YunoHost teríao marcado como completado). É recomendable que investigues o que aconteceu, informando ao equipo de axuda que precisará o rexistro **completo** da migración, pódelo atopar na web de administración en Ferramentas -> Rexistros.",
|
||||||
|
"migration_0027_problematic_apps_warning": "Ten en conta que se atoparon as seguintes apps que poderían ser problemáticas. Semella que non foron instaladas desde o catálogo de aplicacións de YunoHost, ou non están marcadas como que 'funcionan'. Como consecuencia non podemos garantir que seguirán funcionando ben unha vez conclúa a migración: {problematic_apps}",
|
||||||
|
"migration_description_0027_migrate_to_bookworm": "Actualiza o sistema a Debian Bookworm e YunoHost 12",
|
||||||
|
"migration_0027_cleaning_up": "Limpando a caché e os paquetes que xa non son necesarios…",
|
||||||
|
"migration_0027_delayed_api_restart": "A API de YunoHost vaise reiniciar automaticamente en 15 segundos. Durante uns segundos non poderás usala, e despois terás que iniciar sesión outra vez.",
|
||||||
|
"migration_0027_main_upgrade": "A iniciar a actualización principal…",
|
||||||
|
"migration_0027_modified_files": "Detectamos que os seguintes ficheiros semella foron modificados manualmente e poderían ser sobreescritos durante a actualización: {manually_modified_files}",
|
||||||
|
"migration_0027_not_enough_free_space": "Hai moi pouco espazo en /var/! Deberías ter polo menos 1GB libre para realizar a migración.",
|
||||||
|
"migration_0027_patch_yunohost_conflicts": "Aplicando a solución para resolver o problema conflictivo…",
|
||||||
|
"migration_0027_system_not_fully_up_to_date": "O teu sistema non está totalmente actualizado. Fai unha actualización corrente antes de iniciar a migración a Bookworm.",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains": "Dominios que actúan como MX secundario para",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted": "Lista de enderezos para apoio MX de SMTP",
|
||||||
|
"diagnosis_rfkill_wifi": "A tarxeta Wi-Fi está desactivada e un aviso do sistema podería previr a instalación de apps",
|
||||||
|
"diagnosis_rfkill_wifi_details": "Este aviso aparece na saída de varias ordes, estragando algunhas apps. Normalmente require indicar o código de país coa orde <code>sudo raspi-config</code>. Aquí tes o erro:<br>{rfkill_wifi_error}",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains_help": "Permitir a este servidor actuar como un dominio MX *secundario* de apoio para o dominio da lista. Así se o MX principal para o dominio non está accesible (por exemplo por quedar ser electricidade), os correos seguirán enviándose ao servidor, que os gardará un máximo de 20 días e intentará entregalos ao destino real unha vez volva ser accesible. Pódense indicar varios dominios, separados por comas.",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted_help": "Para actuar como MX secundario, hai que proporcionar unha lista detallada de enderezos de correspondentes permitidos (doutro xeito os correos serán rexeitados e desbotados). Pódense indicar varias entradas, separadas por comas."
|
||||||
}
|
}
|
||||||
|
|
433
locales/id.json
433
locales/id.json
|
@ -16,7 +16,7 @@
|
||||||
"app_manifest_install_ask_domain": "Pilih di domain mana aplikasi ini harus dipasang",
|
"app_manifest_install_ask_domain": "Pilih di domain mana aplikasi ini harus dipasang",
|
||||||
"app_not_installed": "Tidak dapat menemukan {app} di daftar aplikasi yang terpasang: {all_apps}",
|
"app_not_installed": "Tidak dapat menemukan {app} di daftar aplikasi yang terpasang: {all_apps}",
|
||||||
"app_not_properly_removed": "{app} belum dilepas dengan benar",
|
"app_not_properly_removed": "{app} belum dilepas dengan benar",
|
||||||
"app_remove_after_failed_install": "Melepas aplikasi setelah kegagalan pemasangan…",
|
"app_remove_after_failed_install": "Menyingkirkan aplikasi setelah kegagalan pemasangan…",
|
||||||
"app_removed": "{app} dilepas",
|
"app_removed": "{app} dilepas",
|
||||||
"app_restore_failed": "Tidak dapat memulihkan {app}: {error}",
|
"app_restore_failed": "Tidak dapat memulihkan {app}: {error}",
|
||||||
"app_upgrade_some_app_failed": "Beberapa aplikasi tidak dapat diperbarui",
|
"app_upgrade_some_app_failed": "Beberapa aplikasi tidak dapat diperbarui",
|
||||||
|
@ -32,14 +32,14 @@
|
||||||
"app_unknown": "Aplikasi tak dikenal",
|
"app_unknown": "Aplikasi tak dikenal",
|
||||||
"ask_new_admin_password": "Kata sandi administrasi baru",
|
"ask_new_admin_password": "Kata sandi administrasi baru",
|
||||||
"ask_password": "Kata sandi",
|
"ask_password": "Kata sandi",
|
||||||
"app_upgrade_app_name": "Memperbarui {app}…",
|
"app_upgrade_app_name": "Sedang meningkatkan {app}…",
|
||||||
"app_upgrade_failed": "Tidak dapat memperbarui {app}: {error}",
|
"app_upgrade_failed": "Tidak dapat memperbarui {app}: {error}",
|
||||||
"app_start_install": "Memasang {app}…",
|
"app_start_install": "Memasang {app}…",
|
||||||
"app_start_remove": "Melepas {app}…",
|
"app_start_remove": "Menyingkirkan {app}…",
|
||||||
"app_manifest_install_ask_password": "Pilih kata sandi administrasi untuk aplikasi ini",
|
"app_manifest_install_ask_password": "Pilih kata sandi administrasi untuk aplikasi ini",
|
||||||
"app_upgrade_several_apps": "Aplikasi berikut akan diperbarui: {apps}",
|
"app_upgrade_several_apps": "Aplikasi berikut akan diperbarui: {apps}",
|
||||||
"backup_app_failed": "Tidak dapat mencadangkan {app}",
|
"backup_app_failed": "Tidak dapat mencadangkan {app}",
|
||||||
"backup_archive_name_exists": "Arsip cadangan dengan nama ini sudah ada.",
|
"backup_archive_name_exists": "Arsip cadangan dengan nama '{name}' ini sudah ada.",
|
||||||
"backup_created": "Cadangan dibuat: {name}",
|
"backup_created": "Cadangan dibuat: {name}",
|
||||||
"backup_creation_failed": "Tidak dapat membuat arsip cadangan",
|
"backup_creation_failed": "Tidak dapat membuat arsip cadangan",
|
||||||
"backup_delete_error": "Tidak dapat menghapus '{path}'",
|
"backup_delete_error": "Tidak dapat menghapus '{path}'",
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
"app_not_upgraded": "Aplikasi '{failed_app}' gagal diperbarui, oleh karena itu pembaruan aplikasi berikut juga dibatalkan: {apps}",
|
"app_not_upgraded": "Aplikasi '{failed_app}' gagal diperbarui, oleh karena itu pembaruan aplikasi berikut juga dibatalkan: {apps}",
|
||||||
"app_config_unable_to_apply": "Gagal menerapkan nilai-nilai panel konfigurasi.",
|
"app_config_unable_to_apply": "Gagal menerapkan nilai-nilai panel konfigurasi.",
|
||||||
"app_config_unable_to_read": "Gagal membaca nilai-nilai panel konfigurasi.",
|
"app_config_unable_to_read": "Gagal membaca nilai-nilai panel konfigurasi.",
|
||||||
"permission_cannot_remove_main": "Menghapus izin utama tidak diperbolehkan",
|
"permission_cannot_remove_main": "Menyingkirkan izin utama tidak diperbolehkan",
|
||||||
"service_description_postgresql": "Menyimpan data aplikasi (basis data SQL)",
|
"service_description_postgresql": "Menyimpan data aplikasi (basis data SQL)",
|
||||||
"restore_already_installed_app": "Aplikasi dengan ID '{app}' telah terpasang",
|
"restore_already_installed_app": "Aplikasi dengan ID '{app}' telah terpasang",
|
||||||
"app_change_url_require_full_domain": "{app} tidak dapat dipindah ke URL baru ini karena ini memerlukan domain penuh (tanpa jalur = /)",
|
"app_change_url_require_full_domain": "{app} tidak dapat dipindah ke URL baru ini karena ini memerlukan domain penuh (tanpa jalur = /)",
|
||||||
|
@ -70,18 +70,18 @@
|
||||||
"app_not_enough_ram": "Aplikasi ini memerlukan {required} RAM untuk pemasangan/pembaruan, tapi sekarang hanya tersedia {current} saja.",
|
"app_not_enough_ram": "Aplikasi ini memerlukan {required} RAM untuk pemasangan/pembaruan, tapi sekarang hanya tersedia {current} saja.",
|
||||||
"app_packaging_format_not_supported": "Aplikasi ini tidak dapat dipasang karena format pengemasan tidak didukung oleh YunoHost versi Anda. Anda sebaiknya memperbarui sistem Anda.",
|
"app_packaging_format_not_supported": "Aplikasi ini tidak dapat dipasang karena format pengemasan tidak didukung oleh YunoHost versi Anda. Anda sebaiknya memperbarui sistem Anda.",
|
||||||
"ask_admin_username": "Nama pengguna admin",
|
"ask_admin_username": "Nama pengguna admin",
|
||||||
"backup_archive_broken_link": "Tidak dapat mengakses arsip cadangan (tautan rusak untuk {path})",
|
"backup_archive_broken_link": "Tidak dapat mengakses arsip cadangan (tautan rusak pada {path})",
|
||||||
"backup_archive_open_failed": "Tidak dapat membuka arsip cadangan",
|
"backup_archive_open_failed": "Tidak dapat membuka arsip cadangan",
|
||||||
"certmanager_cert_install_success_selfsigned": "Sertifikat ditandai sendiri sekarang terpasang untuk '{domain}'",
|
"certmanager_cert_install_success_selfsigned": "Sertifikat ditandai sendiri sekarang terpasang untuk '{domain}'",
|
||||||
"certmanager_cert_renew_failed": "Pembaruan ulang sertifikat Let's Encrypt gagal untuk {domains}",
|
"certmanager_cert_renew_failed": "Pembaruan ulang sertifikat Let's Encrypt gagal untuk {domains}",
|
||||||
"certmanager_cert_renew_success": "Sertifikat Let's Encrypt diperbarui untuk domain '{domain}'",
|
"certmanager_cert_renew_success": "Sertifikat Let's Encrypt diperbarui untuk domain '{domain}'",
|
||||||
"diagnosis_apps_allgood": "Semua aplikasi yang dipasang mengikuti panduan penyusunan yang baik",
|
"diagnosis_apps_allgood": "Semua aplikasi yang dipasang mengikuti panduan pemaketan yang baik",
|
||||||
"diagnosis_basesystem_kernel": "Peladen memakai kernel Linux {kernel_version}",
|
"diagnosis_basesystem_kernel": "Peladen memakai kernel Linux {kernel_version}",
|
||||||
"diagnosis_cache_still_valid": "(Tembolok masih valid untuk diagnosis {category}. Belum akan didiagnosis ulang!)",
|
"diagnosis_cache_still_valid": "(Tembolok masih valid untuk diagnosis {category}. Belum akan didiagnosis ulang!)",
|
||||||
"diagnosis_description_dnsrecords": "Rekaman DNS",
|
"diagnosis_description_dnsrecords": "Rekaman DNS",
|
||||||
"diagnosis_description_ip": "Konektivitas internet",
|
"diagnosis_description_ip": "Konektivitas internet",
|
||||||
"diagnosis_description_web": "Web",
|
"diagnosis_description_web": "Web",
|
||||||
"diagnosis_domain_expiration_error": "Beberapa domain akan kedaluwarsa SEGERA!",
|
"diagnosis_domain_expiration_error": "Beberapa domain akan SEGERA kedaluwarsa!",
|
||||||
"diagnosis_domain_expiration_not_found_details": "Informasi WHOIS untuk domain {domain} sepertinya tidak mengandung informasi tentang tanggal kedaluwarsa?",
|
"diagnosis_domain_expiration_not_found_details": "Informasi WHOIS untuk domain {domain} sepertinya tidak mengandung informasi tentang tanggal kedaluwarsa?",
|
||||||
"diagnosis_domain_expiration_warning": "Beberapa domain akan kedaluwarsa!",
|
"diagnosis_domain_expiration_warning": "Beberapa domain akan kedaluwarsa!",
|
||||||
"diagnosis_domain_expires_in": "{domain} kedaluwarsa dalam {days} hari.",
|
"diagnosis_domain_expires_in": "{domain} kedaluwarsa dalam {days} hari.",
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
"restore_nothings_done": "Tidak ada yang dipulihkan",
|
"restore_nothings_done": "Tidak ada yang dipulihkan",
|
||||||
"restore_running_app_script": "Memulihkan aplikasi {app}…",
|
"restore_running_app_script": "Memulihkan aplikasi {app}…",
|
||||||
"root_password_changed": "kata sandi root telah diubah",
|
"root_password_changed": "kata sandi root telah diubah",
|
||||||
"root_password_desynchronized": "Kata sandi administrasi telah diubah tapi YunoHost tidak dapat mengubahnya menjadi kata sandi root!",
|
"root_password_desynchronized": "Kata sandi administrasi telah diubah, tapi YunoHost tidak dapat mengubahnya menjadi kata sandi root!",
|
||||||
"server_reboot_confirm": "Peladen akan dimulai ulang segera, apakan Anda yakin [{answers}]",
|
"server_reboot_confirm": "Peladen akan dimulai ulang segera, apakan Anda yakin [{answers}]",
|
||||||
"server_shutdown": "Peladen akan dimatikan",
|
"server_shutdown": "Peladen akan dimatikan",
|
||||||
"server_shutdown_confirm": "Peladen akan dimatikan segera, apakah Anda yakin? [{answers}]",
|
"server_shutdown_confirm": "Peladen akan dimatikan segera, apakah Anda yakin? [{answers}]",
|
||||||
|
@ -145,12 +145,12 @@
|
||||||
"user_import_bad_file": "Berkas CSV Anda tidak secara benar diformat, akan diabaikan untuk menghindari potensi data hilang",
|
"user_import_bad_file": "Berkas CSV Anda tidak secara benar diformat, akan diabaikan untuk menghindari potensi data hilang",
|
||||||
"yunohost_postinstall_end_tip": "Proses pasca-pemasangan sudah selesai! Untuk menyelesaikan pengaturan Anda, pertimbangkan:\n - diagnosis masalah yang mungkin lewat bagian 'Diagnosis' di webadmin (atau 'yunohost diagnosis run' di cmd);\n - baca bagian 'Finalizing your setup' dan 'Getting to know YunoHost' di dokumentasi admin: https://yunohost.org/admindoc.",
|
"yunohost_postinstall_end_tip": "Proses pasca-pemasangan sudah selesai! Untuk menyelesaikan pengaturan Anda, pertimbangkan:\n - diagnosis masalah yang mungkin lewat bagian 'Diagnosis' di webadmin (atau 'yunohost diagnosis run' di cmd);\n - baca bagian 'Finalizing your setup' dan 'Getting to know YunoHost' di dokumentasi admin: https://yunohost.org/admindoc.",
|
||||||
"app_already_installed_cant_change_url": "Aplikasi ini sudah terpasang. URL tidak dapat diubah hanya dengan ini. Periksa `app changeurl` jika tersedia.",
|
"app_already_installed_cant_change_url": "Aplikasi ini sudah terpasang. URL tidak dapat diubah hanya dengan ini. Periksa `app changeurl` jika tersedia.",
|
||||||
"app_requirements_checking": "Memeriksa persyaratan untuk {app}…",
|
"app_requirements_checking": "Memeriksa persyaratan pada {app}…",
|
||||||
"backup_create_size_estimation": "Arsip ini akan mengandung data dengan ukuran {size}.",
|
"backup_create_size_estimation": "Arsip ini akan mengandung data dengan ukuran {size}.",
|
||||||
"certmanager_certificate_fetching_or_enabling_failed": "Mencoba untuk menggunakan sertifikat baru untuk {domain} tidak bisa…",
|
"certmanager_certificate_fetching_or_enabling_failed": "Mencoba sertifikat baru pada {domain} tidak dapat digunakan…",
|
||||||
"certmanager_no_cert_file": "Tidak dapat membuka berkas sertifikat untuk domain {domain} (berkas: {file})",
|
"certmanager_no_cert_file": "Tidak dapat membuka berkas sertifikat untuk domain {domain} (berkas: {file})",
|
||||||
"diagnosis_basesystem_hardware": "Arsitektur perangkat keras peladen adalah {virt} {arch}",
|
"diagnosis_basesystem_hardware": "Arsitektur perangkat keras peladen adalah {virt} {arch}",
|
||||||
"diagnosis_basesystem_ynh_inconsistent_versions": "Anda menjalankan versi paket YunoHost yang tidak konsisten… sepertinya karena pembaruan yang gagal.",
|
"diagnosis_basesystem_ynh_inconsistent_versions": "Anda menjalankan versi paket YunoHost yang tidak konsisten… sepertinya karena kegagalan atau sebagian pembaruan.",
|
||||||
"diagnosis_basesystem_ynh_single_version": "versi {package}: {version} ({repo})",
|
"diagnosis_basesystem_ynh_single_version": "versi {package}: {version} ({repo})",
|
||||||
"diagnosis_description_services": "Status layanan",
|
"diagnosis_description_services": "Status layanan",
|
||||||
"diagnosis_description_systemresources": "Sumber daya sistem",
|
"diagnosis_description_systemresources": "Sumber daya sistem",
|
||||||
|
@ -163,7 +163,7 @@
|
||||||
"log_domain_add": "Menambahkan domain '{}' ke konfigurasi sistem",
|
"log_domain_add": "Menambahkan domain '{}' ke konfigurasi sistem",
|
||||||
"main_domain_changed": "Domain utama telah diubah",
|
"main_domain_changed": "Domain utama telah diubah",
|
||||||
"service_already_started": "Layanan '{service}' telah berjalan",
|
"service_already_started": "Layanan '{service}' telah berjalan",
|
||||||
"service_description_fail2ban": "Melindungi dari berbagai macam serangan dari Internet",
|
"service_description_fail2ban": "Melindungi dari serangan kotor dan berbagai macam serangan dari Internet",
|
||||||
"service_description_yunohost-api": "Mengelola interaksi antara antarmuka web YunoHost dengan sistem",
|
"service_description_yunohost-api": "Mengelola interaksi antara antarmuka web YunoHost dengan sistem",
|
||||||
"this_action_broke_dpkg": "Tindakan ini merusak dpkg/APT (pengelola paket sistem)… Anda bisa mencoba menyelesaikan masalah ini dengan masuk lewat SSH dan menjalankan `sudo apt install --fix-broken` dan/atau `sudo dpkg --configure -a`.",
|
"this_action_broke_dpkg": "Tindakan ini merusak dpkg/APT (pengelola paket sistem)… Anda bisa mencoba menyelesaikan masalah ini dengan masuk lewat SSH dan menjalankan `sudo apt install --fix-broken` dan/atau `sudo dpkg --configure -a`.",
|
||||||
"app_manifest_install_ask_init_admin_permission": "Siapa yang boleh mengakses fitur admin untuk aplikasi ini? (Ini bisa diubah nanti)",
|
"app_manifest_install_ask_init_admin_permission": "Siapa yang boleh mengakses fitur admin untuk aplikasi ini? (Ini bisa diubah nanti)",
|
||||||
|
@ -186,7 +186,7 @@
|
||||||
"diagnosis_basesystem_host": "Peladen memakai Debian {debian_version}",
|
"diagnosis_basesystem_host": "Peladen memakai Debian {debian_version}",
|
||||||
"diagnosis_domain_expiration_not_found": "Tidak dapat memeriksa tanggal kedaluwarsa untuk beberapa domain",
|
"diagnosis_domain_expiration_not_found": "Tidak dapat memeriksa tanggal kedaluwarsa untuk beberapa domain",
|
||||||
"diagnosis_http_could_not_diagnose_details": "Galat: {error}",
|
"diagnosis_http_could_not_diagnose_details": "Galat: {error}",
|
||||||
"app_manifest_install_ask_path": "Pilih jalur URL (setelah domain) dimana aplikasi ini akan dipasang",
|
"app_manifest_install_ask_path": "Pilih jalur URL (setelah domain) dimana aplikasi ini harus dipasang",
|
||||||
"certmanager_cert_signing_failed": "Tidak dapat memverifikasi sertifikat baru",
|
"certmanager_cert_signing_failed": "Tidak dapat memverifikasi sertifikat baru",
|
||||||
"config_validate_url": "Harus URL web yang valid",
|
"config_validate_url": "Harus URL web yang valid",
|
||||||
"diagnosis_description_ports": "Penyingkapan porta",
|
"diagnosis_description_ports": "Penyingkapan porta",
|
||||||
|
@ -194,12 +194,12 @@
|
||||||
"mail_unavailable": "Alamat surel ini hanya untuk kelompok admin",
|
"mail_unavailable": "Alamat surel ini hanya untuk kelompok admin",
|
||||||
"main_domain_change_failed": "Tidak dapat mengubah domain utama",
|
"main_domain_change_failed": "Tidak dapat mengubah domain utama",
|
||||||
"diagnosis_ip_global": "IP Global: <code>{global}</code>",
|
"diagnosis_ip_global": "IP Global: <code>{global}</code>",
|
||||||
"diagnosis_ip_dnsresolution_working": "Resolusi nama domain bekerja!",
|
"diagnosis_ip_dnsresolution_working": "Resolusi nama domain bisa digunakan!",
|
||||||
"diagnosis_ip_local": "IP Lokal: <code>{local}</code>",
|
"diagnosis_ip_local": "IP Lokal: <code>{local}</code>",
|
||||||
"diagnosis_ip_no_ipv4": "Peladen ini sepertinya tidak memiliki IPv4.",
|
"diagnosis_ip_no_ipv4": "Peladen ini sepertinya tidak memiliki IPv4.",
|
||||||
"diagnosis_mail_ehlo_could_not_diagnose_details": "Galat: {error}",
|
"diagnosis_mail_ehlo_could_not_diagnose_details": "Galat: {error}",
|
||||||
"global_settings_setting_ssh_password_authentication_help": "Izinkan autentikasi kata sandi untuk SSH",
|
"global_settings_setting_ssh_password_authentication_help": "Izinkan autentikasi kata sandi untuk SSH",
|
||||||
"password_listed": "Kata sandi ini termasuk dalam daftar kata sandi yang sering digunakan di dunia. Mohon untuk memilih yang lebih unik.",
|
"password_listed": "Kata sandi ini termasuk dalam daftar kata sandi yang sering digunakan di dunia. Silakan untuk memilih yang lebih unik.",
|
||||||
"permission_not_found": "Izin '{permission}' tidak ditemukan",
|
"permission_not_found": "Izin '{permission}' tidak ditemukan",
|
||||||
"restore_not_enough_disk_space": "Ruang tidak cukup (ruang: {free_space} B, ruang yang dibutuhkan: {needed_space} B, margin aman: {margin} B)",
|
"restore_not_enough_disk_space": "Ruang tidak cukup (ruang: {free_space} B, ruang yang dibutuhkan: {needed_space} B, margin aman: {margin} B)",
|
||||||
"server_reboot": "Peladen akan dimulai ulang",
|
"server_reboot": "Peladen akan dimulai ulang",
|
||||||
|
@ -211,7 +211,7 @@
|
||||||
"yunohost_configured": "YunoHost sudah terkonfigurasi",
|
"yunohost_configured": "YunoHost sudah terkonfigurasi",
|
||||||
"global_settings_setting_pop3_enabled": "Aktifkan POP3",
|
"global_settings_setting_pop3_enabled": "Aktifkan POP3",
|
||||||
"log_user_import": "Mengimpor pengguna",
|
"log_user_import": "Mengimpor pengguna",
|
||||||
"app_start_backup": "Mengumpulkan berkas untuk dicadangkan untuk {app}…",
|
"app_start_backup": "Mengumpulkan berkas untuk dicadangkan pada {app}…",
|
||||||
"app_upgrade_script_failed": "Galat terjadi di skrip pembaruan aplikasi",
|
"app_upgrade_script_failed": "Galat terjadi di skrip pembaruan aplikasi",
|
||||||
"backup_csv_creation_failed": "Tidak dapat membuat berkas CSV yang dibutuhkan untuk pemulihan",
|
"backup_csv_creation_failed": "Tidak dapat membuat berkas CSV yang dibutuhkan untuk pemulihan",
|
||||||
"certmanager_attempt_to_renew_valid_cert": "Sertifikat untuk domain '{domain}' belum akan kedaluwarsa! (Anda bisa menggunakan --force jika Anda tahu apa yang Anda lakukan)",
|
"certmanager_attempt_to_renew_valid_cert": "Sertifikat untuk domain '{domain}' belum akan kedaluwarsa! (Anda bisa menggunakan --force jika Anda tahu apa yang Anda lakukan)",
|
||||||
|
@ -220,7 +220,7 @@
|
||||||
"upgrade_complete": "Pembaruan selesai",
|
"upgrade_complete": "Pembaruan selesai",
|
||||||
"upgrading_packages": "Memperbarui paket…",
|
"upgrading_packages": "Memperbarui paket…",
|
||||||
"diagnosis_description_apps": "Aplikasi",
|
"diagnosis_description_apps": "Aplikasi",
|
||||||
"diagnosis_description_basesystem": "Basis sistem",
|
"diagnosis_description_basesystem": "Sistem basis",
|
||||||
"global_settings_setting_pop3_enabled_help": "Aktifkan protokol POP3 untuk peladen surel",
|
"global_settings_setting_pop3_enabled_help": "Aktifkan protokol POP3 untuk peladen surel",
|
||||||
"password_confirmation_not_the_same": "Kata sandi dan untuk konfirmasinya tidak sama",
|
"password_confirmation_not_the_same": "Kata sandi dan untuk konfirmasinya tidak sama",
|
||||||
"restore_complete": "Pemulihan selesai",
|
"restore_complete": "Pemulihan selesai",
|
||||||
|
@ -234,7 +234,7 @@
|
||||||
"app_sources_fetch_failed": "Tidak dapat mengambil berkas sumber, apakah URL-nya benar?",
|
"app_sources_fetch_failed": "Tidak dapat mengambil berkas sumber, apakah URL-nya benar?",
|
||||||
"installation_complete": "Pemasangan selesai",
|
"installation_complete": "Pemasangan selesai",
|
||||||
"app_arch_not_supported": "Aplikasi ini hanya bisa dipasang pada arsitektur {required}, tapi arsitektur peladen Anda adalah {current}",
|
"app_arch_not_supported": "Aplikasi ini hanya bisa dipasang pada arsitektur {required}, tapi arsitektur peladen Anda adalah {current}",
|
||||||
"diagnosis_basesystem_hardware_model": "Model peladen adalah {model}",
|
"diagnosis_basesystem_hardware_model": "Model server adalah {model}",
|
||||||
"app_yunohost_version_not_supported": "Aplikasi ini memerlukan YunoHost >= {required}, tapi versi yang terpasang adalah {current}",
|
"app_yunohost_version_not_supported": "Aplikasi ini memerlukan YunoHost >= {required}, tapi versi yang terpasang adalah {current}",
|
||||||
"ask_new_path": "Jalur baru",
|
"ask_new_path": "Jalur baru",
|
||||||
"backup_cleaning_failed": "Tidak dapat menghapus folder cadangan sementara",
|
"backup_cleaning_failed": "Tidak dapat menghapus folder cadangan sementara",
|
||||||
|
@ -252,7 +252,7 @@
|
||||||
"config_validate_email": "Harus surel yang valid",
|
"config_validate_email": "Harus surel yang valid",
|
||||||
"config_apply_failed": "Gagal menerapkan konfigurasi baru: {error}",
|
"config_apply_failed": "Gagal menerapkan konfigurasi baru: {error}",
|
||||||
"diagnosis_basesystem_ynh_main_version": "Peladen memakai YunoHost {main_version} ({repo})",
|
"diagnosis_basesystem_ynh_main_version": "Peladen memakai YunoHost {main_version} ({repo})",
|
||||||
"diagnosis_cant_run_because_of_dep": "Tidak dapat menjalankan diagnosis untuk {category} ketika ada masalah utama yang terkait dengan {dep}.",
|
"diagnosis_cant_run_because_of_dep": "Tidak dapat menjalankan diagnosis pada {category} ketika ada masalah utama yang terkait dengan {dep}.",
|
||||||
"diagnosis_services_conf_broken": "Konfigurasi rusak untuk layanan {service}!",
|
"diagnosis_services_conf_broken": "Konfigurasi rusak untuk layanan {service}!",
|
||||||
"diagnosis_services_running": "Layanan {service} berjalan!",
|
"diagnosis_services_running": "Layanan {service} berjalan!",
|
||||||
"diagnosis_swap_ok": "Sistem ini memiliki {total} swap!",
|
"diagnosis_swap_ok": "Sistem ini memiliki {total} swap!",
|
||||||
|
@ -277,7 +277,7 @@
|
||||||
"diagnosis_ip_connected_ipv6": "Peladen ini terhubung ke internet lewat IPv6!",
|
"diagnosis_ip_connected_ipv6": "Peladen ini terhubung ke internet lewat IPv6!",
|
||||||
"diagnosis_services_bad_status": "Layanan {service} {status} :(",
|
"diagnosis_services_bad_status": "Layanan {service} {status} :(",
|
||||||
"global_settings_setting_root_password": "Kata sandi root baru",
|
"global_settings_setting_root_password": "Kata sandi root baru",
|
||||||
"log_app_action_run": "Menjalankan tindakan dari aplikasi '{}'",
|
"log_app_action_run": "Menjalankan tindakan pada aplikasi '{}'",
|
||||||
"log_settings_reset_all": "Atur ulang semua pengaturan",
|
"log_settings_reset_all": "Atur ulang semua pengaturan",
|
||||||
"log_settings_set": "Terapkan pengaturan",
|
"log_settings_set": "Terapkan pengaturan",
|
||||||
"service_removed": "Layanan '{service}' dihapus",
|
"service_removed": "Layanan '{service}' dihapus",
|
||||||
|
@ -296,7 +296,7 @@
|
||||||
"upnp_disabled": "UPnP dimatikan",
|
"upnp_disabled": "UPnP dimatikan",
|
||||||
"global_settings_setting_smtp_allow_ipv6_help": "Perbolehkan penggunaan IPv6 untuk menerima dan mengirim surel",
|
"global_settings_setting_smtp_allow_ipv6_help": "Perbolehkan penggunaan IPv6 untuk menerima dan mengirim surel",
|
||||||
"domain_config_default_app": "Aplikasi baku",
|
"domain_config_default_app": "Aplikasi baku",
|
||||||
"diagnosis_diskusage_verylow": "Penyimpanan <code>{mountpoint}</code> (di perangkat <code>{device}</code>) hanya tinggal memiliki {free} ({free_percent}%) ruang kosong yang tersedia (dari {total}). Direkomendasikan untuk membersihkan ruang penyimpanan!",
|
"diagnosis_diskusage_verylow": "Penyimpanan <code>{mountpoint}</code> (di perangkat <code>{device}</code>) hanya memiliki {free} ({free_percent}%) ruang kosong yang tersedia (dari {total}). Sebaiknya Anda mempertimbangkan untuk membersihkan ruang penyimpanan!",
|
||||||
"domain_config_api_protocol": "Protokol API",
|
"domain_config_api_protocol": "Protokol API",
|
||||||
"domain_config_cert_summary_letsencrypt": "Bagus! Anda menggunakan sertifikat Let's Encrypt yang valid!",
|
"domain_config_cert_summary_letsencrypt": "Bagus! Anda menggunakan sertifikat Let's Encrypt yang valid!",
|
||||||
"domain_config_mail_out": "Surel keluar",
|
"domain_config_mail_out": "Surel keluar",
|
||||||
|
@ -325,19 +325,19 @@
|
||||||
"domain_config_cert_summary_ok": "Oke, sertifikat saat ini terlihat bagus!",
|
"domain_config_cert_summary_ok": "Oke, sertifikat saat ini terlihat bagus!",
|
||||||
"app_failed_to_upgrade_but_continue": "Gagal memperbarui aplikasi {failed_app}, melanjutkan pembaruan berikutnya seperti yang diminta. Jalankan 'yunohost log show {operation_logger_name}' untuk melihat log kegagalan",
|
"app_failed_to_upgrade_but_continue": "Gagal memperbarui aplikasi {failed_app}, melanjutkan pembaruan berikutnya seperti yang diminta. Jalankan 'yunohost log show {operation_logger_name}' untuk melihat log kegagalan",
|
||||||
"certmanager_attempt_to_replace_valid_cert": "Anda sedang mencoba untuk menimpa sertifikat yang valid untuk domain {domain}! (Gunakan --force untuk melewati ini)",
|
"certmanager_attempt_to_replace_valid_cert": "Anda sedang mencoba untuk menimpa sertifikat yang valid untuk domain {domain}! (Gunakan --force untuk melewati ini)",
|
||||||
"permission_protected": "Izin {permission} dilindungi. Anda tidak dapat menambahkan atau menghapus kelompok pengunjung ke/dari izin ini.",
|
"permission_protected": "Izin {permission} dilindungi. Anda tidak dapat menambahkan atau menyingkirkan grup pengunjung ke/dari izin ini.",
|
||||||
"permission_require_account": "Izin {permission} hanya masuk akal untuk pengguna yang memiliki akun, maka ini tidak dapat diaktifkan untuk pengunjung.",
|
"permission_require_account": "Izin {permission} hanya masuk akal untuk pengguna yang memiliki akun, maka ini tidak dapat diaktifkan untuk pengunjung.",
|
||||||
"permission_update_failed": "Tidak dapat memperbarui izin '{permission}': {error}",
|
"permission_update_failed": "Tidak dapat memperbarui izin '{permission}': {error}",
|
||||||
"apps_failed_to_upgrade": "Aplikasi berikut gagal untuk diperbarui:{apps}",
|
"apps_failed_to_upgrade": "Aplikasi berikut gagal untuk diperbarui:{apps}",
|
||||||
"backup_archive_name_unknown": "Arsip cadangan lokal tidak diketahui yang bernama '{name}'",
|
"backup_archive_name_unknown": "Arsip cadangan lokal dengan nama '{name}' tidak diketahui",
|
||||||
"diagnosis_http_nginx_conf_not_up_to_date_details": "Untuk memperbaiki ini, periksa perbedaannya dari CLI menggunakan <cmd>yunohost tools regen-conf nginx --dry-run --with-diff</cmd> dan jika Anda sudah, terapkan perubahannya menggunakan <cmd>yunohost tools regen-conf nginx --force</cmd>.",
|
"diagnosis_http_nginx_conf_not_up_to_date_details": "Untuk memperbaiki ini, periksa perbedaannya dari CLI menggunakan <cmd>yunohost tools regen-conf nginx --dry-run --with-diff</cmd> dan jika menurut Anda sudah sesuai, terapkan perubahannya menggunakan <cmd>yunohost tools regen-conf nginx --force</cmd>.",
|
||||||
"domain_config_auth_token": "Token autentikasi",
|
"domain_config_auth_token": "Token autentikasi",
|
||||||
"domain_config_cert_install": "Pasang sertifikat Let's Encrypt",
|
"domain_config_cert_install": "Pasang sertifikat Let's Encrypt",
|
||||||
"domain_config_cert_summary_abouttoexpire": "Sertifikat saat ini akan kedaluwarsa. Akan secara otomatis diperbarui secepatnya.",
|
"domain_config_cert_summary_abouttoexpire": "Sertifikat saat ini akan kedaluwarsa. Akan secara otomatis diperbarui secepatnya.",
|
||||||
"domain_config_mail_in": "Surel datang",
|
"domain_config_mail_in": "Surel datang",
|
||||||
"password_too_simple_1": "Panjang kata sandi harus paling tidak 8 karakter",
|
"password_too_simple_1": "Panjang kata sandi harus paling tidak 8 karakter",
|
||||||
"password_too_simple_2": "Panjang kata sandi harus paling tidak 8 karakter dan mengandung digit, huruf kapital, dan huruf kecil",
|
"password_too_simple_2": "Kata sandi harus terdiri dari minimal 8 karakter dan berisi karakter angka, besar, dan kecil",
|
||||||
"password_too_simple_3": "Panjang kata sandi harus paling tidak 8 karakter dan mengandung digit, huruf kapital, huruf kecil, dan karakter khusus",
|
"password_too_simple_3": "Kata sandi harus terdiri dari minimal 8 karakter dan berisi karakter angka, besar, kecil dan khusus",
|
||||||
"password_too_simple_4": "Panjang kata sandi harus paling tidak 12 karakter dan mengandung digit, huruf kapital, huruf kecil, dan karakter khusus",
|
"password_too_simple_4": "Panjang kata sandi harus paling tidak 12 karakter dan mengandung digit, huruf kapital, huruf kecil, dan karakter khusus",
|
||||||
"port_already_closed": "Porta {port} telah ditutup untuk koneksi {ip_version}",
|
"port_already_closed": "Porta {port} telah ditutup untuk koneksi {ip_version}",
|
||||||
"service_description_yunomdns": "Membuat Anda bisa menemukan peladen Anda menggunakan 'yunohost.local' di jaringan lokal Anda",
|
"service_description_yunomdns": "Membuat Anda bisa menemukan peladen Anda menggunakan 'yunohost.local' di jaringan lokal Anda",
|
||||||
|
@ -351,7 +351,7 @@
|
||||||
"regenconf_now_managed_by_yunohost": "Berkas konfigurasi '{conf}' sekarang dikelola oleh YunoHost (kategori {category}).",
|
"regenconf_now_managed_by_yunohost": "Berkas konfigurasi '{conf}' sekarang dikelola oleh YunoHost (kategori {category}).",
|
||||||
"regenconf_updated": "Konfigurasi diperbarui untuk '{category}'",
|
"regenconf_updated": "Konfigurasi diperbarui untuk '{category}'",
|
||||||
"log_user_group_delete": "Menghapus kelompok '{}'",
|
"log_user_group_delete": "Menghapus kelompok '{}'",
|
||||||
"backup_archive_cant_retrieve_info_json": "Tidak dapat memuat info untuk arsip '{archive}'… Berkas info.json tidak dapat didapakan (atau bukan json yang valid).",
|
"backup_archive_cant_retrieve_info_json": "Tidak dapat memuat info pada arsip '{archive}'… Berkas info.json tidak dapat dipulihkan (atau bukan json yang valid).",
|
||||||
"diagnosis_mail_blacklist_reason": "Alasan pendaftarhitaman adalah: {reason}",
|
"diagnosis_mail_blacklist_reason": "Alasan pendaftarhitaman adalah: {reason}",
|
||||||
"diagnosis_ports_unreachable": "Porta {port} tidak tercapai dari luar.",
|
"diagnosis_ports_unreachable": "Porta {port} tidak tercapai dari luar.",
|
||||||
"diagnosis_ram_verylow": "Sistem hanya memiliki {available} ({available_percent}%) RAM yang tersedia! (dari {total})",
|
"diagnosis_ram_verylow": "Sistem hanya memiliki {available} ({available_percent}%) RAM yang tersedia! (dari {total})",
|
||||||
|
@ -366,7 +366,7 @@
|
||||||
"log_permission_create": "Membuat izin '{}'",
|
"log_permission_create": "Membuat izin '{}'",
|
||||||
"log_permission_delete": "Menghapus izin '{}'",
|
"log_permission_delete": "Menghapus izin '{}'",
|
||||||
"backup_with_no_backup_script_for_app": "Aplikasi '{app}' tidak memiliki skrip pencadangan. Mengabaikan.",
|
"backup_with_no_backup_script_for_app": "Aplikasi '{app}' tidak memiliki skrip pencadangan. Mengabaikan.",
|
||||||
"backup_system_part_failed": "Tidak dapat mencadangkan bagian '{part}' sistem",
|
"backup_system_part_failed": "Tidak dapat mencadangkan bagian sistem '{part}'",
|
||||||
"log_user_create": "Menambahkan pengguna '{}'",
|
"log_user_create": "Menambahkan pengguna '{}'",
|
||||||
"log_user_delete": "Menghapus pengguna '{}'",
|
"log_user_delete": "Menghapus pengguna '{}'",
|
||||||
"log_user_group_create": "Membuat kelompok '{}'",
|
"log_user_group_create": "Membuat kelompok '{}'",
|
||||||
|
@ -377,7 +377,7 @@
|
||||||
"diagnosis_dns_point_to_doc": "Silakan periksa dokumentasi di <a href='https://yunohost.org/dns_config'>https://yunohost.org/dns_config</a> jika Anda masih membutuhkan bantuan untuk mengatur rekaman DNS.",
|
"diagnosis_dns_point_to_doc": "Silakan periksa dokumentasi di <a href='https://yunohost.org/dns_config'>https://yunohost.org/dns_config</a> jika Anda masih membutuhkan bantuan untuk mengatur rekaman DNS.",
|
||||||
"diagnosis_regenconf_manually_modified": "Berkas konfigurasi <code>{file}</code> sepertinya telah diubah manual.",
|
"diagnosis_regenconf_manually_modified": "Berkas konfigurasi <code>{file}</code> sepertinya telah diubah manual.",
|
||||||
"backup_with_no_restore_script_for_app": "{app} tidak memiliki skrip pemulihan, Anda tidak akan bisa secara otomatis memulihkan cadangan aplikasi ini.",
|
"backup_with_no_restore_script_for_app": "{app} tidak memiliki skrip pemulihan, Anda tidak akan bisa secara otomatis memulihkan cadangan aplikasi ini.",
|
||||||
"config_no_panel": "Tidak dapat menemukan panel konfigurasi.",
|
"config_no_panel": "Panel konfigurasi tidak ditemukan.",
|
||||||
"confirm_app_install_warning": "Peringatan: Aplikasi ini mungkin masih bisa bekerja, tapi tidak terintegrasi dengan baik dengan YunoHost. Beberapa fitur seperti SSO dan pencadangan mungkin tidak tersedia. Tetap pasang? [{answers}] ",
|
"confirm_app_install_warning": "Peringatan: Aplikasi ini mungkin masih bisa bekerja, tapi tidak terintegrasi dengan baik dengan YunoHost. Beberapa fitur seperti SSO dan pencadangan mungkin tidak tersedia. Tetap pasang? [{answers}] ",
|
||||||
"diagnosis_ports_ok": "Porta {port} tercapai dari luar.",
|
"diagnosis_ports_ok": "Porta {port} tercapai dari luar.",
|
||||||
"diagnosis_ports_partially_unreachable": "Porta {port} tidak tercapai dari luar lewat IPv{failed}.",
|
"diagnosis_ports_partially_unreachable": "Porta {port} tidak tercapai dari luar lewat IPv{failed}.",
|
||||||
|
@ -393,7 +393,7 @@
|
||||||
"log_user_permission_reset": "Mengatur ulang izin '{}'",
|
"log_user_permission_reset": "Mengatur ulang izin '{}'",
|
||||||
"domain_config_xmpp": "Pesan Langsung (XMPP)",
|
"domain_config_xmpp": "Pesan Langsung (XMPP)",
|
||||||
"diagnosis_http_connection_error": "Masalah jaringan: tidak dapat terhubung dengan domain yang diminta, sangat mungkin terputus.",
|
"diagnosis_http_connection_error": "Masalah jaringan: tidak dapat terhubung dengan domain yang diminta, sangat mungkin terputus.",
|
||||||
"dyndns_ip_updated": "IP Anda diperbarui di DynDNS",
|
"dyndns_ip_updated": "IP Anda diperbarui pada DynDNS",
|
||||||
"ask_dyndns_recovery_password_explain": "Pilih kata sandi pemulihan untuk domain DynDNS Anda.",
|
"ask_dyndns_recovery_password_explain": "Pilih kata sandi pemulihan untuk domain DynDNS Anda.",
|
||||||
"ask_dyndns_recovery_password": "Kata sandi pemulihan DynDNS",
|
"ask_dyndns_recovery_password": "Kata sandi pemulihan DynDNS",
|
||||||
"backup_output_directory_not_empty": "Anda harus memilih direktori yang kosong",
|
"backup_output_directory_not_empty": "Anda harus memilih direktori yang kosong",
|
||||||
|
@ -440,5 +440,374 @@
|
||||||
"restore_system_part_failed": "Tidak dapat memulihkan segmen '{part}'",
|
"restore_system_part_failed": "Tidak dapat memulihkan segmen '{part}'",
|
||||||
"service_enable_failed": "Tidak dapat membuat layanan '{service}' dimulai mandiri saat pemulaian.\n\nLog layanan baru-baru ini:{logs}",
|
"service_enable_failed": "Tidak dapat membuat layanan '{service}' dimulai mandiri saat pemulaian.\n\nLog layanan baru-baru ini:{logs}",
|
||||||
"service_not_reloading_because_conf_broken": "Tidak memuat atau memulai ulang layanan '{name}' karena konfigurasinya rusak: {errors}",
|
"service_not_reloading_because_conf_broken": "Tidak memuat atau memulai ulang layanan '{name}' karena konfigurasinya rusak: {errors}",
|
||||||
"service_reloaded": "Layanan {service} dimuat ulang"
|
"service_reloaded": "Layanan {service} dimuat ulang",
|
||||||
|
"additional_urls_already_removed": "URL tambahan '{url}' sudah disingkirkan pada URL tambahan untuk perizinan '{permission}'",
|
||||||
|
"additional_urls_already_added": "URL tambahan '{url}' sudah ditambahkan pada URL tambahan untuk perizinan '{permission}'",
|
||||||
|
"app_argument_password_no_default": "Galat ketika mengurai argumen sandi '{name}': argumen sandi tidak diperbolehkan mempunyai suatu nilai baku demi alasan keamanan",
|
||||||
|
"app_corrupt_source": "YunoHost telah berhasil mengunduh aset tersebut '{source_id}' ({url}) untuk {app}, tetapi aset tidak sesuai dengan checksum. Hal ini bisa jadi karena beberapa jaringan temporer mengalami kegagalan pada peladen Anda, ATAU entah bagaimana aset mengalami perubahan oleh penyelenggara hulu (atau pelakon jahat?) dan pemaket YunoHost perlu untuk menyelidiki dan mungkin pembaruan manifes applikasi tersebut untuk mempertimbangkan perubahan ini.\n\tEkspektasi checksum sha256: {expected_sha256}\n\tUnduhan checksum sha256: {computed_sha256}\n\tUnduhan ukuran berkas: {size}",
|
||||||
|
"app_not_upgraded_broken_system": "Aplikasi '{failed_app}' telah gagal meningkatkan dan menyebabkan sistem dalam status rusak, dan sebagai konsekuensi terhadap peningkatan aplikasi tersebut telah dibatalkan: {apps}",
|
||||||
|
"app_resource_failed": "Menyediakan, membatalkan penyediaan, atau memperbarui sumber daya pada {app} telah gagal: {error}",
|
||||||
|
"app_failed_to_download_asset": "Gagal mengunduh aset '{source_id}' ({url}) untuk {app}: {out}",
|
||||||
|
"apps_catalog_init_success": "Inisialisasi sistem katalog aplikasi!",
|
||||||
|
"app_unsupported_remote_type": "Tidak mendukung type remot yang digunakan pada aplikasi",
|
||||||
|
"app_not_upgraded_broken_system_continue": "Aplikasi '{failed_app}' telah gagal meningkatkan dan menyebabkan sistem dalam status rusak (jadi --continue-on-failure diabaikan), dan sebagai konsekuensi terhadap peningkatan aplikasi tersebut telah dibatalkan: {apps}",
|
||||||
|
"apps_failed_to_upgrade_line": "\n * {app_id}(untuk melihat log yang berkaitan lakukan 'yunohost log show {operation_logger_name}')",
|
||||||
|
"backup_couldnt_bind": "Tidak dapat memaut {src} ke {dest}.",
|
||||||
|
"backup_custom_mount_error": "Metode pencadangan khusus tidak dapat melewati langkah 'mount'",
|
||||||
|
"backup_hook_unknown": "Kait cadangan '{hook}' tidak diketahui",
|
||||||
|
"backup_method_custom_finished": "Metode pencadangan khusus '{method}' selesai",
|
||||||
|
"backup_cant_mount_uncompress_archive": "Tidak dapat memasang arsip yang tidak terkompres sebagai proteksi penulisan",
|
||||||
|
"backup_custom_backup_error": "Metode pencadangan khusus tidak dapat melewati langkah 'backup'",
|
||||||
|
"backup_no_uncompress_archive_dir": "Tidak ada direktori arsip yang tidak terkompres",
|
||||||
|
"backup_unable_to_organize_files": "Tidak dapat menggunakan metode cepat untuk mengatur berkas dalam arsip",
|
||||||
|
"certmanager_cannot_read_cert": "Terjadi kesalahan saat mencoba membuka sertifikat saat ini untuk domain {domain} (berkas: {file}), alasan: {reason}",
|
||||||
|
"certmanager_domain_not_diagnosed_yet": "Belum ada hasil diagnosis untuk domain {domain}. Silakan jalankan kembali diagnosis untuk kategori 'DNS records' dan 'Web' di bagian diagnosis untuk memeriksa apakah domain siap untuk Let's Encrypt. (Atau jika Anda tahu apa yang Anda lakukan, gunakan '--no-checks' untuk mematikan pemeriksaan ini.)",
|
||||||
|
"certmanager_warning_subdomain_dns_record": "Subdomain '{subdomain}' tidak memiliki alamat IP yang sama dengan '{domain}'. Beberapa fitur tidak akan tersedia sampai Anda memperbaikinya dan membuat ulang sertifikat.",
|
||||||
|
"confirm_notifications_read": "PERINGATAN: Anda harus memeriksa notifikasi pada aplikasi di atas sebelum melanjutkan, mungkin terdapat hal yang penting untuk diketahui. [{answers}]",
|
||||||
|
"diagnosis_apps_broken": "Aplikasi tersebut saat ini ditandai sebagai rusak pada katalog aplikasi YunoHost. Ini mungkin hanya isu sementara ketika pengelola berupaya memperbaiki masalah tersebut. Untuk sementara, peningkatan versi aplikasi ini dinonaktifkan.",
|
||||||
|
"backup_running_hooks": "Menjalankan kait cadangan…",
|
||||||
|
"config_unknown_filter_key": "Kunci filter '{filter_key}' tidak sesuai.",
|
||||||
|
"backup_permission": "Izin pencadangan untuk {app}",
|
||||||
|
"config_forbidden_keyword": "Kata kunci '{keyword}' sudah ada, Anda tidak dapat membuat atau menggunakan panel konfigurasi disertai pertanyaan dengan id ini.",
|
||||||
|
"good_practices_about_user_password": "Sekarang Anda akan menentukan kata sandi pengguna baru. Kata sandi harus terdiri dari minimal 8 karakter—meskipun sebaiknya menggunakan kata sandi yang lebih panjang (misalnya parafrasa) dan/atau menggunakan beragam karakter (huruf besar, huruf kecil, angka, dan karakter khusus).",
|
||||||
|
"domain_dns_push_failed_to_authenticate": "Autentikasi gagal pada API registrar untuk domain '{domain}'. Besar kemungkinan karena kredensial tidak sesuai? (Galat: {error})",
|
||||||
|
"certmanager_domain_dns_ip_differs_from_public_ip": "Rekaman DNS untuk domain '{domain}' berbeda dengan IP server ini. Silakan periksa kategori 'Catatan DNS' (dasar) dalam diagnosis untuk info lebih lanjut. Jika Anda baru saja memodifikasi rekaman A, silakan menunggu hingga rekaman tersebut disebarkan (beberapa pemeriksa sebaran DNS tersedia online). (Jika Anda tahu apa yang Anda lakukan, gunakan '--no-checks' untuk mematikan pemeriksaan ini.)",
|
||||||
|
"certmanager_hit_rate_limit": "Terlalu banyak sertifikat yang telah diterbitkan untuk kumpulan domain {domain} ini baru-baru ini. Silakan coba lagi nanti. Lihat https://letsencrypt.org/docs/rate-limits/ untuk detail lebih lanjut",
|
||||||
|
"custom_app_url_required": "Anda harus memberikan URL untuk meningkatkan versi aplikasi khusus Anda {app}",
|
||||||
|
"ask_dyndns_recovery_password_explain_unavailable": "Domain DynDNS ini sudah terdaftar. Jika Anda adalah orang yang pertama kali mendaftarkan domain ini, Anda dapat memasukkan kata sandi pemulihan untuk mengeklaim kembali domain ini.",
|
||||||
|
"backup_archive_writing_error": "Tidak bisa menambahkan berkas '{source}' (disebutkan dalam arsip '{dest}') untuk dicadangkan ke dalam arsip yang terkompres '{archive}'",
|
||||||
|
"certmanager_domain_http_not_working": "Domain {domain} sepertinya tidak dapat diakses melalui HTTP. Silakan periksa kategori 'Web' dalam diagnosis untuk info lebih lanjut. (Jika Anda tahu apa yang Anda lakukan, gunakan '--no-checks' untuk mematikan pemeriksaan ini.)",
|
||||||
|
"diagnosis_apps_bad_quality": "Aplikasi tersebut saat ini ditandai sebagai rusak pada katalog aplikasi YunoHost. Ini mungkin hanya isu sementara ketika pengelola berupaya memperbaiki masalah tersebut. Untuk sementara, peningkatan versi aplikasi ini dinonaktifkan.",
|
||||||
|
"backup_output_directory_required": "Anda harus menyediakan direktori keluaran untuk cadangan tersebut",
|
||||||
|
"config_action_disabled": "Tidak dapat menjalankan aksi '{action}' karena dinonaktifkan, pastikan untuk memenuhi batasannya. bantuan: {help}",
|
||||||
|
"config_cant_set_value_on_section": "Anda tidak dapat menetapkan satu nilai pun di seluruh bagian konfigurasi.",
|
||||||
|
"backup_applying_method_custom": "Memanggil metode pencadangan khusus '{method}'…",
|
||||||
|
"backup_ask_for_copying_if_needed": "Apakah Anda ingin melakukan pencadangan menggunakan {size}MB untuk sementara? (Cara ini digunakan karena beberapa berkas tidak dapat disiapkan menggunakan metode yang lebih efisien.)",
|
||||||
|
"good_practices_about_admin_password": "Sekarang Anda akan menentukan kata sandi administrasi baru. Kata sandi harus terdiri dari minimal 8 karakter—meskipun sebaiknya menggunakan kata sandi yang lebih panjang (misalnya parafrasa) dan/atau menggunakan beragam karakter (huruf besar, huruf kecil, angka, dan karakter khusus).",
|
||||||
|
"certmanager_acme_not_configured_for_domain": "Tantangan ACME tidak dapat dijalankan untuk {domain} saat ini karena konfigurasi pada nginx tidak memiliki potongan kode yang sesuai… Pastikan konfigurasi nginx Anda mutakhir menggunakan `yunohost tools regen-conf nginx --dry-run --with-diff`.",
|
||||||
|
"diagnosis_http_special_use_tld": "Domain {domain} berdasarkan pada domain tingkat atas (TLD) penggunaan khusus seperti .local atau .test dan oleh karena itu tidak diharapkan untuk diekspos di luar jaringan lokal.",
|
||||||
|
"certmanager_self_ca_conf_file_not_found": "Tidak dapat menemukan berkas konfigurasi untuk otoritas teken mandiri (berkas: {file})",
|
||||||
|
"diagnosis_dns_specialusedomain": "Domain {domain} didasarkan pada domain tingkat atas (TLD) penggunaan khusus seperti .local atau .test dan oleh karena itu tidak diharapkan memiliki data DNS yang sebenarnya.",
|
||||||
|
"certmanager_unable_to_parse_self_CA_name": "Tidak dapat menguraikan nama otoritas teken mandiri (berkas: {file})",
|
||||||
|
"confirm_app_install_danger": "BAHAYA! Aplikasi ini diketahui masih eksperimental (jika tidak secara eksplisit tidak berfungsi)! Anda mungkin TIDAK boleh menginstalnya kecuali Anda tahu apa yang Anda lakukan. TIDAK ADA DUKUNGAN yang akan diberikan jika aplikasi ini tidak berfungsi atau merusak sistem Anda… Jika Anda tetap bersedia mengambil risiko tersebut, ketik '{answers}'",
|
||||||
|
"diagnosis_dns_missing_record": "Sesuai dengan konfigurasi DNS yang direkomendasikan, Anda harus menambahkan data DNS dengan info berikut.<br>Jenis: <code>{type}</code><br>Nama: <code>{name}</code><br >Nilai: <code>{value}</code>",
|
||||||
|
"diagnosis_http_could_not_diagnose": "Tidak dapat mendiagnosis apakah domain dapat dijangkau dari luar pada IPv{ipversion}.",
|
||||||
|
"diagnosis_found_errors_and_warnings": "Ditemukan {errors} isu penting (dan {warnings} peringatan) terkait dengan {category}!",
|
||||||
|
"diagnosis_http_hairpinning_issue": "Jaringan lokal Anda sepertinya tidak mengaktifkan hairpinning.",
|
||||||
|
"diagnosis_http_partially_unreachable": "Domain {domain} tampaknya tidak dapat dijangkau melalui HTTP dari luar jaringan lokal di IPv{failed}, meskipun berfungsi di IPv{passed}.",
|
||||||
|
"confirm_app_insufficient_ram": "BAHAYA! Aplikasi ini memerlukan {required} RAM untuk menginstal/meningkatkan tetapi hanya {current} yang tersedia saat ini. Meskipun aplikasi ini dapat berjalan, proses instalasi/peningkatannya memerlukan RAM dalam jumlah besar sehingga server Anda mungkin macet dan gagal total. Jika Anda tetap bersedia mengambil risiko tersebut, ketik '{answers}'",
|
||||||
|
"confirm_app_install_thirdparty": "BAHAYA! Aplikasi ini bukan bagian dari katalog aplikasi YunoHost. Memasang aplikasi pihak ketiga dapat membahayakan integritas dan keamanan sistem Anda. Mungkin Anda TIDAK boleh menginstalnya kecuali Anda tahu apa yang Anda lakukan. TIDAK ADA DUKUNGAN yang akan diberikan jika aplikasi ini tidak berfungsi atau merusak sistem Anda… Jika Anda tetap bersedia mengambil risiko tersebut, ketik '{answers}'",
|
||||||
|
"diagnosis_dns_discrepancy": "Data DNS berikut tampaknya tidak mengikuti konfigurasi yang disarankan:<br>Tipe: <code>{type}</code><br>Nama: <code>{name}</code><br>Nilai saat ini: < code>{current}</code><br>Nilai yang diharapkan: <code>{value}</code>",
|
||||||
|
"diagnosis_high_number_auth_failures": "Ada sejumlah besar kegagalan autentikasi yang mencurigakan baru-baru ini. Anda mungkin ingin memastikan bahwa fail2ban berjalan dan dikonfigurasi dengan benar, atau menggunakan port khusus untuk SSH seperti yang dijelaskan di https://yunohost.org/security.",
|
||||||
|
"diagnosis_dns_try_dyndns_update_force": "Konfigurasi DNS domain ini secara otomatis dikelola oleh YunoHost. Jika tidak, Anda dapat mencoba memaksa pembaruan menggunakan <cmd>yunohost dyndns update --force</cmd>.",
|
||||||
|
"diagnosis_http_hairpinning_issue_details": "Ini mungkin karena kotak / router ISP Anda. Akibatnya, orang dari luar jaringan lokal Anda akan dapat mengakses server Anda seperti yang diharapkan, tetapi bukan orang dari dalam jaringan lokal (seperti Anda, mungkin?) saat menggunakan nama domain atau IP global. Anda mungkin dapat memperbaiki situasi ini dengan melihat <a href='https://yunohost.org/dns_local_network'>https://yunohost.org/dns_local_network</a>",
|
||||||
|
"diagnosis_found_warnings": "Ditemukan {warnings} bagian yang dapat ditingkatkan pada {category}.",
|
||||||
|
"diagnosis_apps_outdated_ynh_requirement": "Versi terinstal aplikasi ini hanya memerlukan yunohost >= 2.x atau 3.x, yang cenderung menunjukkan bahwa versi tersebut tidak mutakhir dengan praktik pengemasan dan bantuan yang direkomendasikan. Anda harus benar-benar mempertimbangkan untuk memutakhirkannya.",
|
||||||
|
"config_forbidden_readonly_type": "Tipe '{type}' tidak dapat disetel sebagai hanya baca, gunakan tipe lain untuk mengubah nilai ini (id argumen yang relevan: '{id}').",
|
||||||
|
"diagnosis_mail_blacklist_listed_by": "IP atau domain Anda <code>{item}</code> masuk daftar hitam pada {blacklist_name}",
|
||||||
|
"diagnosis_mail_ehlo_bad_answer": "Layanan non-SMTP dijawab pada port 25 di IPv{ipversion}",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked": "Server pos SMTP tidak dapat mengirim email ke server lain karena port keluar 25 diblokir pada IPv{ipversion}.",
|
||||||
|
"diagnosis_mail_queue_ok": "{nb_pending} surel tertunda di antrean pos",
|
||||||
|
"diagnosis_mail_outgoing_port_25_ok": "Server pos SMTP dapat mengirim surel (port keluar 25 tidak diblokir).",
|
||||||
|
"diagnosis_ram_low": "Sistem memiliki {available} ({available_percent}%) RAM yang tersedia (dari {total}). Hati-hati.",
|
||||||
|
"diagnosis_ram_ok": "Sistem masih memiliki {available} ({available_percent}%) RAM yang tersedia dari {total}.",
|
||||||
|
"diagnosis_mail_fcrdns_dns_missing": "Tidak ada reverse-DNS yang ditentukan dalam IPv{ipversion}. Beberapa surel mungkin gagal terkirim atau ditandai sebagai spam.",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked_details": "Anda harus terlebih dahulu mencoba membuka blokir port keluar 25 di antarmuka router internet atau antarmuka penyedia hosting Anda. (Beberapa penyedia hosting mungkin meminta Anda mengirimi mereka tiket dukungan untuk ini).",
|
||||||
|
"diagnosis_ignored_issues": "(+ {nb_ignored} isu yang diabaikan)",
|
||||||
|
"diagnosis_no_cache": "Belum ada cache diagnosis untuk kategori '{category}'",
|
||||||
|
"diagnosis_mail_queue_unavailable": "Tidak dapat melihat jumlah surel yang tertunda dalam antrean",
|
||||||
|
"diagnosis_http_unreachable": "Domain {domain} tampaknya tidak dapat dijangkau melalui HTTP dari luar jaringan lokal.",
|
||||||
|
"diagnosis_ip_weird_resolvconf": "Resolusi DNS tampaknya berfungsi, namun sepertinya Anda menggunakan <code>/etc/resolv.conf</code> khusus.",
|
||||||
|
"diagnosis_mail_ehlo_could_not_diagnose": "Tidak dapat mendiagnosis apakah server pos postfix dapat dijangkau dari luar pada IPv{ipversion}.",
|
||||||
|
"diagnosis_mail_ehlo_ok": "Server pos SMTP dapat dijangkau dari luar sehingga dapat menerima email!",
|
||||||
|
"diagnosis_mail_blacklist_website": "Setelah mengidentifikasi alasan Anda terdaftar dan memperbaikinya, silakan meminta IP atau domain Anda agar disingkirkan di {blacklist_website}",
|
||||||
|
"diagnosis_processes_killed_by_oom_reaper": "Beberapa proses baru-baru ini dihentikan oleh sistem karena kehabisan memori. Hal ini biasanya merupakan gejala dari kurangnya memori pada sistem atau proses yang memakan terlalu banyak memori. Ringkasan proses yang dihentikan:\n{kills_summary}",
|
||||||
|
"diagnosis_mail_ehlo_wrong": "Server pos SMTP yang berbeda menjawab pada IPv{ipversion}. Server Anda mungkin tidak dapat menerima email.",
|
||||||
|
"diagnosis_ip_broken_resolvconf": "Resolusi nama domain tampaknya rusak pada server Anda, yang tampaknya terkait dengan <code>/etc/resolv.conf</code> tidak mengarah ke <code>127.0.0.1</code>.",
|
||||||
|
"diagnosis_mail_fcrdns_nok_details": "Anda harus terlebih dahulu mencoba mengonfigurasi reverse-DNS dengan <code>{ehlo_domain}</code> di antarmuka router internet atau antarmuka penyedia hosting Anda. (Beberapa penyedia hosting mungkin meminta Anda mengirimi mereka tiket dukungan untuk ini).",
|
||||||
|
"diagnosis_mail_fcrdns_ok": "Reverse-DNS Anda telah dikonfigurasi dengan benar!",
|
||||||
|
"diagnosis_http_bad_status_code": "Sepertinya komputer lain (mungkin router internet Anda) yang menjawab bukannya server Anda.<br>1. Penyebab paling umum dari isu ini adalah port 80 (dan 443) <a href='https://yunohost.org/isp_box_config'>tidak diteruskan dengan benar ke server Anda</a>.<br>2. Pada pengaturan yang lebih rumit: pastikan tidak ada firewall atau reverse-proxy yang mengganggu.",
|
||||||
|
"diagnosis_mail_ehlo_unreachable_details": "Tidak dapat membuka koneksi pada port 25 ke server Anda di IPv{ipversion}. Tampaknya tidak dapat dijangkau.<br>1. Penyebab paling umum dari masalah ini adalah port 25 <a href='https://yunohost.org/isp_box_config'>tidak diteruskan dengan benar ke server Anda</a>.<br>2. Anda juga harus memastikan bahwa layanan postfix berjalan.<br>3. Pada pengaturan yang lebih rumit: pastikan tidak ada firewall atau proxy terbalik yang mengganggu.",
|
||||||
|
"diagnosis_ip_weird_resolvconf_details": "Berkas <code>/etc/resolv.conf</code> harus berupa symlink ke <code>/etc/resolvconf/run/resolv.conf</code> itu sendiri yang menunjuk ke <code>127.0.0.1</code> (dnsmasq). Jika Anda ingin mengatur DNS resolver secara manual, silakan edit <code>/etc/resolv.dnsmasq.conf</code>.",
|
||||||
|
"diagnosis_mail_ehlo_wrong_details": "EHLO yang diterima oleh pemeriksa jarak jauh di IPv{ipversion} berbeda dengan domain server Anda.<br>EHLO yang diterima: <code>{wrong_ehlo}</code><br>Diharapkan: <code>{right_ehlo}</code> <br>Penyebab paling umum dari masalah ini adalah port 25 <a href='https://yunohost.org/isp_box_config'>tidak diteruskan dengan benar ke server Anda</a>. Alternatifnya, pastikan tidak ada firewall atau reverse-proxy yang mengganggu.",
|
||||||
|
"diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Beberapa penyedia tidak mengizinkan Anda membuka blokir port keluar 25 karena mereka tidak peduli dengan Netralitas Net.<br> - Beberapa dari mereka memberikan alternatif <a href='https://yunohost.org/email_configure_relay'>menggunakan server pos relai</a> meskipun hal ini menyiratkan bahwa relai akan dapat memata-matai lalu lintas surel Anda.<br>- Alternatif yang lebih ramah privasi adalah menggunakan VPN *dengan IP publik khusus* untuk melewati batasan semacam ini . Lihat <a href='https://yunohost.org/vpn_advantage'>https://yunohost.org/vpn_advantage</a><br>- Anda juga dapat mempertimbangkan untuk beralih ke <a href='https://yunohost .org/isp'>penyedia yang lebih ramah terhadap netralitas</a>",
|
||||||
|
"diagnosis_ignore_already_filtered": "(Sudah ada filter diagnosis {category} dengan kriteria ini)",
|
||||||
|
"diagnosis_ignore_no_filter_found": "(Tidak ada filter {category} diagnosis dengan kriteria ini yang harus disingkirkan)",
|
||||||
|
"diagnosis_ignore_criteria_error": "Kriteria harus dalam bentuk key=value (cth. domain=yolo.test)",
|
||||||
|
"diagnosis_ignore_filter_added": "Menambahkan filter diagnosis {category}",
|
||||||
|
"diagnosis_ignore_filter_removed": "Menyingkirkan filter diagnosis {category}",
|
||||||
|
"diagnosis_never_ran_yet": "Sepertinya server ini baru saja tertata dan belum ada laporan diagnosis yang ditampilkan. Anda harus memulai dengan menjalankan diagnosis lengkap, baik dari webadmin atau menggunakan 'yunohost diagnosis run' dari baris perintah.",
|
||||||
|
"diagnosis_backports_in_sources_list": "Sepertinya apt (manajer paket) dikonfigurasi untuk menggunakan depot backports. Kecuali Anda benar-benar tahu apa yang Anda lakukan, kami sangat tidak menyarankan memasang paket dari backport, karena kemungkinan besar akan menjadi labil atau konflik pada sistem Anda.",
|
||||||
|
"diagnosis_mail_fcrdns_nok_alternatives_6": "Beberapa penyedia tidak mengizinkan Anda mengonfigurasi reverse-DNS (atau fitur mereka mungkin rusak…). Jika reverse-DNS Anda dikonfigurasi dengan benar untuk IPv4, Anda dapat mencoba menonaktifkan penggunaan IPv6 saat mengirim surel dengan menjalankan <cmd>yunohost settings set email.smtp.smtp_allow_ipv6 -v off</cmd>. Catatan: dengan solusi tersebut berarti Anda tidak akan bisa mengirim atau menerima surel dari beberapa server khusus IPv6 di luar sana.",
|
||||||
|
"diagnosis_http_timeout": "Waktu habis saat mencoba menghubungi server Anda dari luar. Tampaknya tidak dapat dijangkau.<br>1. Penyebab paling umum dari masalah ini adalah port 80 (dan 443) <a href='https://yunohost.org/isp_box_config'>tidak diteruskan dengan benar ke server Anda</a>.<br>2. Anda juga harus memastikan bahwa layanan nginx berjalan<br>3. Pada pengaturan yang lebih rumit: pastikan tidak ada firewall atau reverse-proxy yang mengganggu.",
|
||||||
|
"diagnosis_mail_ehlo_bad_answer_details": "Ini mungkin disebabkan oleh mesin lain yang menjawab bukannya server Anda.",
|
||||||
|
"diagnosis_package_installed_from_sury": "Beberapa paket sistem harus diturunkan versinya",
|
||||||
|
"diagnosis_ports_could_not_diagnose_details": "Galat: {error}",
|
||||||
|
"diagnosis_mail_fcrdns_different_from_ehlo_domain": "Reverse-DNS tidak dikonfigurasi dengan benar pada IPv{ipversion}. Beberapa surel mungkin gagal terkirim atau ditandai sebagai spam.",
|
||||||
|
"diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Reverse-DNS saat ini: <code>{rdns_domain}</code><br>Nilai yang diharapkan: <code>{ehlo_domain}</code>",
|
||||||
|
"diagnosis_package_installed_from_sury_details": "Beberapa paket secara tidak sengaja dipasang dari depot pihak ketiga bernama Sury. Tim YunoHost meningkatkan strategi dalam menangani paket tersebut, namun diperkirakan bahwa beberapa pengaturan aplikasi yang terpasang PHP7.3 saat masih dalam Stretch masih memiliki beberapa inkonsistensi. Untuk memperbaiki situasi ini, Anda harus mencoba menjalankan perintah berikut: <cmd>{cmd_to_fix}</cmd>",
|
||||||
|
"diagnosis_ports_needed_by": "Mengekspos port ini diperlukan untuk fitur {category} (layanan {service})",
|
||||||
|
"diagnosis_mail_fcrdns_nok_alternatives_4": "Beberapa penyedia tidak mengizinkan Anda mengonfigurasi reverse-DNS (atau fitur mereka mungkin rusak…). Jika Anda mengalami isu karena hal ini, pertimbangkan solusi berikut:<br> - Beberapa ISP menyediakan alternatif <a href='https://yunohost.org/email_configure_relay'>menggunakan server pos relai</a> ini menyiratkan bahwa relai akan dapat memata-matai lalu lintas surel Anda.<br>- Alternatif ramah privasi adalah menggunakan VPN *dengan IP publik khusus* untuk melewati batasan semacam ini. Lihat <a href='https://yunohost.org/vpn_advantage'>https://yunohost.org/vpn_advantage</a><br>- Atau bisa juga ke <a href='https://yunohost.org /isp'>beralih ke penyedia lain</a>",
|
||||||
|
"diagnosis_ip_broken_dnsresolution": "Resolusi nama domain tampaknya rusak karena beberapa alasan… Apakah firewall memblokir permintaan DNS?",
|
||||||
|
"diagnosis_mail_queue_too_big": "Terlalu banyak surel yang tertunda dalam antrean pos ({nb_pending} surel)",
|
||||||
|
"diagnosis_ports_could_not_diagnose": "Tidak dapat mendiagnosis apakah port dapat dijangkau dari luar pada IPv{ipversion}.",
|
||||||
|
"diagnosis_ports_forwarding_tip": "Untuk memperbaiki masalah ini, kemungkinan besar Anda perlu mengonfigurasi penerusan port pada router internet Anda seperti yang dijelaskan di <a href='https://yunohost.org/isp_box_config'>https://yunohost.org/isp_box_config</a>",
|
||||||
|
"diagnosis_mail_ehlo_unreachable": "Server pos SMTP tidak dapat dijangkau dari luar pada IPv{ipversion}. Itu tidak akan dapat menerima email.",
|
||||||
|
"diagnosis_ignore_missing_criteria": "Anda harus memberikan setidaknya satu kriteria sebagai kategori diagnosis untuk diabaikan",
|
||||||
|
"diagnosis_ignore_no_issue_found": "Tidak menemukan isu yang sesuai dengan kriteria tersebut.",
|
||||||
|
"domain_dns_push_already_up_to_date": "Rekaman sudah diperbarui, biarkan saja.",
|
||||||
|
"domain_cannot_remove_main_add_new_one": "Anda tidak dapat menyingkirkan '{domain}' karena ini adalah domain utama dan satu-satunya domain Anda, Anda harus menambahkan domain lain terlebih dahulu menggunakan 'yunohost domain add <domain-lain.com>', kemudian menetapkannya sebagai domain utama menggunakan 'yunohost domain main-domain -n <domain-lain.com>' kemudian Anda dapat menyingkirkan domain '{domain}' menggunakan 'yunohost domain remove {domain}'.",
|
||||||
|
"diagnosis_sshd_config_insecure": "Konfigurasi SSH tampaknya telah dimodifikasi secara manual, dan tidak aman karena tidak berisi pedoman 'AllowGroups' atau 'AllowUsers' untuk membatasi akses kepada pengguna yang berwenang.",
|
||||||
|
"diagnosis_unknown_categories": "Kategori berikut tidak diketahui: {categories}",
|
||||||
|
"domain_dns_conf_is_just_a_recommendation": "Perintah ini menunjukkan kepada Anda konfigurasi yang *direkomendasikan*. Ini sebenarnya tidak mengatur konfigurasi DNS untuk Anda. Anda bertanggung jawab untuk mengonfigurasi zona DNS di registrar Anda sesuai dengan rekomendasi ini.",
|
||||||
|
"diagnosis_sshd_config_inconsistent": "Sepertinya port SSH telah dimodifikasi secara manual di /etc/ssh/sshd_config. Sejak YunoHost 4.2, pengaturan global baru 'security.ssh.ssh_port' tersedia untuk menghindari pengeditan konfigurasi secara manual.",
|
||||||
|
"disk_space_not_sufficient_install": "Ruang disket yang tersisa tidak cukup untuk memasang aplikasi ini",
|
||||||
|
"domain_cannot_add_muc_upload": "Anda tidak dapat menambahkan domain yang dimulai dengan 'muc.'. Nama seperti ini dicadangkan untuk fitur obrolan multi-pengguna XMPP yang terintegrasi ke dalam YunoHost.",
|
||||||
|
"domain_config_auth_application_key": "Kunci aplikasi",
|
||||||
|
"domain_config_auth_application_secret": "Kunci rahasia aplikasi",
|
||||||
|
"domain_config_auth_consumer_key": "Kunci konsumen",
|
||||||
|
"diagnosis_rootfstotalspace_warning": "Sistem file root hanya memiliki total {space}. Ini mungkin oke, tapi hati-hati karena pada akhirnya Anda mungkin akan kehabisan ruang disket dengan cepat… Disarankan untuk memiliki setidaknya 16 GB untuk sistem file root.",
|
||||||
|
"diagnosis_swap_tip": "Harap berhati-hati dan sadari bahwa jika server adalah hosting swap pada kartu SD atau penyimpanan SSD, hal ini dapat mengurangi masa pakai perangkat secara drastis.",
|
||||||
|
"diagnosis_regenconf_manually_modified_details": "Ini mungkin OK jika Anda tahu apa yang Anda lakukan! YunoHost akan berhenti memperbarui file ini secara otomatis… Namun berhati-hatilah karena pemutakhiran YunoHost mungkin berisi perubahan penting yang disarankan. Jika mau, Anda dapat memeriksa perbedaannya dengan <cmd>yunohost tools regen-conf {category} --dry-run --with-diff</cmd> dan memaksa reset ke konfigurasi yang disarankan dengan <cmd>yunohost tools regen-conf {category} --force</cmd>",
|
||||||
|
"diagnosis_rootfstotalspace_critical": "Sistem berkas root hanya memiliki total {space} yang cukup mengkhawatirkan! Kemungkinan besar Anda akan kehabisan ruang disket dengan sangat cepat! Disarankan untuk memiliki setidaknya 16 GB untuk sistem berkas root.",
|
||||||
|
"domain_config_acme_eligible_explain": "Sepertinya domain ini belum siap untuk sertifikat Let's Encrypt. Silakan periksa konfigurasi DNS dan jangkauan server HTTP Anda. Bagian 'Rekaman DNS' dan 'Web' di <a href='#/diagnosis'>laman diagnosis</a> dapat membantu Anda memahami apa yang salah dalam konfigurasi.",
|
||||||
|
"domain_config_cert_issuer": "Otoritas sertifikasi",
|
||||||
|
"domain_config_cert_renew_help": "Sertifikat akan diperpanjang secara otomatis selama 15 hari validitas terakhir. Anda dapat memperbaruinya secara manual jika Anda mau. (Tidak direkomendasikan).",
|
||||||
|
"domain_config_cert_summary_selfsigned": "PERINGATAN: Sertifikat saat ini ditandatangani sendiri. Browser akan menampilkan peringatan seram kepada pengunjung baru!",
|
||||||
|
"domain_config_xmpp_help": "Catatan: beberapa fitur XMPP mengharuskan Anda memperbarui rekaman DNS dan membuat ulang sertifikat Lets Encrypt agar dapat diaktifkan",
|
||||||
|
"domain_dns_conf_special_use_tld": "Domain ini berdasarkan pada domain tingkat atas (TLD) penggunaan khusus seperti .local atau .test dan oleh karena itu tidak diharapkan memiliki rekaman DNS yang sesungguhnya.",
|
||||||
|
"domain_dns_push_failed": "Gagal total dalam memperbarui rekaman DNS.",
|
||||||
|
"diagnosis_using_stable_codename_details": "Biasanya hal ini disebabkan oleh kesalahan konfigurasi dari penyedia hosting Anda. Ini berbahaya, karena segera setelah versi Debian berikutnya menjadi 'stable' yang baru, <cmd>apt</cmd> akan melakukan upgrade pada semua paket sistem tanpa melalui prosedur migrasi yang benar. Disarankan untuk memperbaikinya dengan mengedit sumber apt untuk depot dasar Debian, dan mengganti kata kunci <cmd>stable</cmd> dengan <cmd>bullseye</cmd>. Berkas konfigurasi yang sesuai harus <cmd>/etc/apt/sources.list</cmd>, atau berkas dalam <cmd>/etc/apt/sources.list.d/</cmd>.",
|
||||||
|
"domain_cannot_add_xmpp_upload": "Anda tidak dapat menambahkan domain yang dimulai dengan 'xmpp-upload.'. Nama seperti ini dicadangkan untuk fitur unggah XMPP yang terintegrasi ke dalam YunoHost.",
|
||||||
|
"diagnosis_using_yunohost_testing": "<cmd>apt</cmd> (manajer paket sistem) saat ini dikonfigurasi agar memasang pemutakhiran 'testing' apa pun untuk inti YunoHost.",
|
||||||
|
"diagnosis_using_yunohost_testing_details": "Ini mungkin OK jika Anda tahu apa yang Anda lakukan, tapi perhatikan catatan rilis sebelum memasang pemutakhiran YunoHost! Jika Anda ingin menonaktifkan peningkatan 'testing', Anda harus menghapus kata kunci <cmd>testing</cmd> dari <cmd>/etc/apt/sources.list.d/yunohost.list</cmd>.",
|
||||||
|
"domain_cannot_remove_main": "Anda tidak dapat menyingkirkan '{domain}' karena ini adalah domain utama, Anda harus terlebih dahulu menetapkan domain lain sebagai domain utama menggunakan 'yunohost domain main-domain -n <domain-lain>'; berikut daftar kandidat domain: {other_domains}",
|
||||||
|
"domain_config_acme_eligible": "Kelayakan ACME",
|
||||||
|
"domain_config_auth_entrypoint": "Titik entri API",
|
||||||
|
"diagnosis_swap_notsomuch": "Sistem hanya memiliki {total} swap. Anda harus mempertimbangkan untuk memiliki setidaknya {recommended} untuk menghindari situasi di mana sistem kehabisan memori.",
|
||||||
|
"domain_config_cert_validity": "Validitas",
|
||||||
|
"domain_config_default_app_help": "Orang-orang akan secara otomatis diarahkan ke aplikasi ini ketika membuka domain ini. Jika tidak ada aplikasi yang ditentukan, orang-orang akan diarahkan ke formulir login portal pengguna.",
|
||||||
|
"diagnosis_services_bad_status_tip": "Anda dapat mencoba <a href='#/services/{service}'>mengulang layanan</a>, dan jika tidak berhasil, lihat <a href='#/services/{service} '>log layanan pada webadmin</a> (dari baris perintah, Anda dapat melakukannya dengan <cmd>yunohost service restart {service}</cmd> dan <cmd>yunohost service log {service}</cmd> ).",
|
||||||
|
"diagnosis_sshd_config_inconsistent_details": "Silakan jalankan <cmd>yunohost settings set security.ssh.ssh_port -v PORT_SSH_ANDA</cmd> untuk menentukan port SSH, dan periksa <cmd>yunohost tools regen-conf ssh --dry-run --with-diff</cmd > dan <cmd>yunohost tools regen-conf ssh --force</cmd> untuk mengatur ulang konfigurasi Anda sesuai rekomendasi YunoHost.",
|
||||||
|
"diagnosis_swap_none": "Sistem tidak memiliki swap sama sekali. Anda harus mempertimbangkan untuk menambahkan setidaknya {recommended} swap untuk menghindari situasi di mana sistem kehabisan memori.",
|
||||||
|
"diagnosis_using_stable_codename": "<cmd>apt</cmd> (pengelola paket sistem) saat ini dikonfigurasi untuk memasang paket dari nama kode 'stable', bukan nama kode versi Debian saat ini (bullseye).",
|
||||||
|
"disk_space_not_sufficient_update": "Ruang disket yang tersisa tidak cukup untuk memperbarui aplikasi ini",
|
||||||
|
"domain_config_auth_key": "Kunci otentikasi",
|
||||||
|
"domain_config_auth_secret": "Rahasia otentikasi",
|
||||||
|
"domain_dns_push_record_failed": "Gagal mencatat {action} {type}/{name} : {error}",
|
||||||
|
"domain_dns_push_managed_in_parent_domain": "Fitur konfigurasi DNS otomatis dikelola di domain induk {parent_domain}.",
|
||||||
|
"domain_dns_pushing": "Mendorong rekaman DNS…",
|
||||||
|
"domain_dns_push_not_applicable": "Fitur konfigurasi DNS otomatis tidak berlaku untuk domain {domain}. Anda harus mengonfigurasi rekaman DNS Anda secara manual dengan mengikuti dokumentasi di https://yunohost.org/dns_config.",
|
||||||
|
"domain_dns_registrar_experimental": "Sejauh ini, antarmuka dengan API **{registrar}** belum diuji dan ditinjau dengan benar oleh komunitas YunoHost. Dukungan masih **sangat eksperimental** - waspadalah!",
|
||||||
|
"domain_dns_push_partial_failure": "Rekaman DNS diperbarui sebagian: beberapa peringatan/galat dilaporkan.",
|
||||||
|
"domain_dns_registrar_not_supported": "YunoHost tidak dapat secara otomatis mendeteksi registrar yang menangani domain ini. Anda harus mengonfigurasi rekaman DNS Anda secara manual dengan mengikuti dokumentasi di https://yunohost.org/dns.",
|
||||||
|
"domain_dns_push_failed_to_list": "Gagal mencantumkan rekaman saat ini menggunakan API registrar: {error}",
|
||||||
|
"domain_dns_push_success": "Rekaman DNS diperbarui!",
|
||||||
|
"domain_dns_registrar_managed_in_parent_domain": "Domain ini adalah subdomain dari {parent_domain_link}. Konfigurasi registrar DNS harus dikelola di panel konfigurasi {parent_domain}.",
|
||||||
|
"dyndns_domain_not_provided": "Penyedia DynDNS {provider} tidak dapat menyediakan domain {domain}.",
|
||||||
|
"dyndns_key_not_found": "Kunci DNS tidak ditemukan di domain tersebut",
|
||||||
|
"dyndns_no_domain_registered": "Tidak ada domain yang terdaftar pada DynDNS",
|
||||||
|
"domain_registrar_is_not_configured": "Registrar belum dikonfigurasi untuk domain {domain}.",
|
||||||
|
"domain_unknown": "Domain '{domain}' tidak diketahui",
|
||||||
|
"dyndns_provider_unreachable": "Tidak dapat menghubungi penyedia DynDNS {provider}: YunoHost Anda tidak terhubung dengan benar ke internet atau server dynette sedang kolaps.",
|
||||||
|
"dyndns_subscribe_failed": "Tidak dapat berlangganan domain DynDNS: {error}",
|
||||||
|
"dyndns_subscribed": "Berlangganan domain di DynDNS",
|
||||||
|
"domain_hostname_failed": "Tidak dapat menetapkan nama host baru. Ini mungkin menimbulkan masalah di kemudian hari (mungkin baik-baik saja).",
|
||||||
|
"dyndns_could_not_check_available": "Tidak dapat memeriksa apakah {domain} tersedia di {provider}.",
|
||||||
|
"dyndns_too_many_requests": "Layanan dyndns YunoHost menerima terlalu banyak permintaan dari Anda, tunggu sekitar 1 jam sebelum mencoba lagi.",
|
||||||
|
"domain_dns_registrar_yunohost": "Domain ini adalah nohost.me / nohost.st / ynh.fr dan oleh karena itu konfigurasi DNS tersebut secara otomatis akan ditangani oleh YunoHost tanpa konfigurasi lebih lanjut. (lihat perintah 'yunohost dyndns update')",
|
||||||
|
"dpkg_lock_not_available": "Perintah ini tidak dapat dijalankan sekarang karena program lain sepertinya menggunakan kunci pada dpkg (manajer paket sistem)",
|
||||||
|
"domain_dns_registrar_supported": "YunoHost secara otomatis mendeteksi bahwa domain ini ditangani oleh registrar **{registrar}**. Jika Anda mau, YunoHost akan secara otomatis mengonfigurasi zona DNS ini, jika Anda memberikan kredensial API yang sesuai. Anda dapat menemukan dokumentasi mengenai cara mendapatkan kredensial API Anda di halaman ini: https://yunohost.org/registar_api_{registrar}. (Anda juga dapat mengonfigurasi rekaman DNS Anda secara manual dengan mengikuti dokumentasi di https://yunohost.org/dns )",
|
||||||
|
"dyndns_no_recovery_password": "Tidak ada kata sandi pemulihan yang ditentukan! Jika Anda kehilangan kendali atas domain ini, Anda perlu menghubungi administrator di tim YunoHost!",
|
||||||
|
"domain_dyndns_already_subscribed": "Anda sudah berlangganan domain pada DynDNS",
|
||||||
|
"dyndns_unsubscribe_already_unsubscribed": "Domain sudah berhenti berlangganan",
|
||||||
|
"dyndns_unsubscribe_denied": "Gagal berhenti berlangganan domain: kredensial tidak valid",
|
||||||
|
"dyndns_unsubscribe_failed": "Tidak dapat berhenti berlangganan domain DynDNS: {error}",
|
||||||
|
"dpkg_is_broken": "Anda tidak dapat melakukan ini sekarang karena dpkg/APT (manajer paket sistem) sepertinya dalam keadaan rusak… Anda dapat mencoba menyelesaikan masalah ini melalui koneksi SSH dan menjalankan `sudo apt install --fix-broken` dan/atau `sudo dpkg --configure -a` dan/atau `sudo dpkg --audit`.",
|
||||||
|
"user_import_bad_line": "Baris yang salah {line}: {details}",
|
||||||
|
"permission_already_disallowed": "Grup '{group}' sudah menonaktifkan izin '{permission}'",
|
||||||
|
"migration_0027_start": "Memulai migrasi ke Bookworm…",
|
||||||
|
"global_settings_setting_smtp_relay_host": "Host relai SMTP",
|
||||||
|
"group_cannot_edit_all_users": "Grup 'all_users' tidak dapat diedit secara manual. Ini adalah grup khusus yang dimaksudkan untuk menampung semua pengguna yang terdaftar di YunoHost",
|
||||||
|
"group_cannot_be_deleted": "Grup {group} tidak dapat dihapus secara manual.",
|
||||||
|
"unlimit": "Tidak ada kuota",
|
||||||
|
"migration_0027_still_on_bullseye_after_main_upgrade": "Ada yang tidak sesuai ketika menjalankan pemutakhiran utama, sistem tampaknya masih menggunakan Debian Bullseye.",
|
||||||
|
"pattern_lastname": "Harus berupa nama belakang yang valid (minimal 3 karakter)",
|
||||||
|
"global_settings_setting_backup_compress_tar_archives": "Memadatkan cadangan",
|
||||||
|
"firewall_rules_cmd_failed": "Beberapa perintah aturan firewall gagal. Info lebih lanjut di dalam log.",
|
||||||
|
"global_settings_setting_admin_strength": "Persyaratan kualitas kata sandi admin",
|
||||||
|
"global_settings_setting_dns_exposure_help": "NB: Ini hanya mempengaruhi konfigurasi DNS yang disarankan dan pemeriksaan diagnosis. Ini tidak mempengaruhi konfigurasi sistem.",
|
||||||
|
"global_settings_setting_nginx_compatibility": "Kompatibilitas NGINX",
|
||||||
|
"global_settings_setting_security_experimental_enabled": "Fitur keamanan eksperimental",
|
||||||
|
"iptables_unavailable": "Anda tidak dapat menggunakan iptables di sini. Anda berada dalam sebuah penampungan atau kernel Anda yang tidak mendukungnya",
|
||||||
|
"ldap_attribute_already_exists": "Atribut LDAP '{attribute}' sudah ada dengan nilai '{value}'",
|
||||||
|
"log_does_exists": "Tidak ada log operasi dengan nama '{log}', gunakan 'yunohost log list' untuk melihat semua log operasi yang tersedia",
|
||||||
|
"log_dyndns_unsubscribe": "Berhenti berlangganan subdomain YunoHost '{}'",
|
||||||
|
"migrations_dependencies_not_satisfied": "Jalankan migrasi berikut: '{dependencies_id}', sebelum migrasi {id}.",
|
||||||
|
"permission_already_allowed": "Grup '{group}' sudah mengaktifkan izin '{permission}'",
|
||||||
|
"group_unknown": "Grup '{group}' tidak diketahui",
|
||||||
|
"global_settings_setting_smtp_relay_port": "Porta relai SMTP",
|
||||||
|
"global_settings_setting_smtp_relay_user": "Pengguna relai SMTP",
|
||||||
|
"group_update_failed": "Tidak dapat memperbarui grup '{group}': {error}",
|
||||||
|
"pattern_domain": "Harus berupa nama domain yang valid (misalnya domain-saya.org)",
|
||||||
|
"show_tile_cant_be_enabled_for_regex": "Anda tidak dapat mengaktifkan 'show_tile' saat ini, karena URL untuk perizinan '{permission}' adalah regex",
|
||||||
|
"show_tile_cant_be_enabled_for_url_not_defined": "Anda tidak dapat mengaktifkan 'show_tile' saat ini, karena Anda harus terlebih dahulu menentukan URL pada perizinan '{permission}'",
|
||||||
|
"ldap_server_down": "Tidak dapat menjangkau server LDAP",
|
||||||
|
"update_apt_cache_failed": "Tidak dapat memperbarui cache APT (manajer paket Debian). Berikut ini adalah kumpulan baris source.list, yang mungkin dapat membantu mengidentifikasi baris yang bermasalah:\n{sourceslist}",
|
||||||
|
"user_import_failed": "Operasi impor pengguna gagal total",
|
||||||
|
"invalid_number_min": "Harus lebih besar dari {min}",
|
||||||
|
"log_help_to_get_failed_log": "Operasi '{desc}' tidak dapat diselesaikan. Silakan memberi log lengkap operasi ini menggunakan perintah 'yunohost log share {name}' untuk mendapatkan bantuan",
|
||||||
|
"mail_domain_unknown": "Alamat surel tidak valid untuk domain '{domain}'. Silakan, menggunakan domain yang dikelola oleh server ini.",
|
||||||
|
"mailbox_used_space_dovecot_down": "Layanan kotak pos Dovecot harus aktif jika Anda ingin mengambil ruang kotak pos yang telah digunakan",
|
||||||
|
"migration_0023_postgresql_11_not_installed": "PostgreSQL belum terpasang pada sistem Anda. Biarkan saja.",
|
||||||
|
"migration_ldap_backup_before_migration": "Membuat cadangan basis data LDAP dan pengaturan aplikasi sebelum migrasi yang sebenarnya.",
|
||||||
|
"migrations_not_pending_cant_skip": "Migrasi ini tidak tertunda, sehingga tidak dapat dilewati: {ids}",
|
||||||
|
"operation_interrupted": "Operasinya dihentikan secara manual?",
|
||||||
|
"unexpected_error": "Terjadi kesalahan yang tidak terduga: {error}",
|
||||||
|
"log_help_to_get_log": "Untuk melihat log operasi '{desc}', gunakan perintah 'yunohost log show {name}'",
|
||||||
|
"migration_0021_cleaning_up": "Membersihkan tembolok dan paket yang sudah tidak berguna…",
|
||||||
|
"invalid_number_max": "Harus kurang dari {max}",
|
||||||
|
"migration_0027_yunohost_upgrade": "Memulai pemutakhiran inti YunoHost…",
|
||||||
|
"migration_description_0022_php73_to_php74_pools": "Migrasi berkas konfigurasi 'pool' php7.3-fpm ke php7.4",
|
||||||
|
"migration_description_0027_migrate_to_bookworm": "pemutakhiran sistem ke Debian Bookworm dan YunoHost 12",
|
||||||
|
"migrations_exclusive_options": "'--auto', '--skip', dan '--force-rerun' adalah opsi khusus yang saling berkaitan.",
|
||||||
|
"migrations_failed_to_load_migration": "Tidak dapat memuat migrasi {id}: {error}",
|
||||||
|
"field_invalid": "Bidang '{}' tidak valid",
|
||||||
|
"migrations_migration_has_failed": "Migrasi {id} tidak lengkap, dibatalkan. Galat: {exception}",
|
||||||
|
"migrations_must_provide_explicit_targets": "Anda harus memberikan target yang jelas saat menggunakan '--skip' atau '--force-rerun'",
|
||||||
|
"group_already_exist_on_system": "Grup {group} sudah ada di dalam grup sistem",
|
||||||
|
"migrations_pending_cant_rerun": "Migrasi ini masih tertunda, sehingga belum bisa dijalankan lagi: {ids}",
|
||||||
|
"regenconf_failed": "Tidak dapat membuat ulang konfigurasi pada kategori: {categories}",
|
||||||
|
"global_settings_setting_postfix_compatibility": "Kompatibilitas Postfix",
|
||||||
|
"restore_cleaning_failed": "Tidak dapat membersihkan direktori restorasi sementara",
|
||||||
|
"other_available_options": "… dan {n} opsi lain yang tersedia tidak ditampilkan",
|
||||||
|
"restore_confirm_yunohost_installed": "Apakah Anda benar-benar ingin memulihkan sistem yang sudah terpasang? [{answers}]",
|
||||||
|
"global_settings_setting_postfix_compatibility_help": "Kompatibilas versus kompromi keamanan untuk server Postfix. Mempengaruhi kerahasian (dan aspek terkait keamanan lainnya)",
|
||||||
|
"user_import_partial_failed": "Operasi impor pengguna gagal sebagian",
|
||||||
|
"log_regen_conf": "Membuat ulang konfigurasi sistem '{}'",
|
||||||
|
"permission_currently_allowed_for_all_users": "Izin ini sekarang diberikan kepada semua pengguna selain grup yang lain. Anda mungkin ingin menyingkirkan izin 'all_users' atau menyingkirkan grup lain yang saat ini diberikan izin tersebut.",
|
||||||
|
"restore_running_hooks": "Menjalankan kait restorasi…",
|
||||||
|
"dyndns_unsubscribed": "Berhenti berlangganan domain DynDNS",
|
||||||
|
"global_settings_setting_backup_compress_tar_archives_help": "Ketika membuat cadangan baru, padatkan arsip (.tar.gz) dan bukannya arsip yang tidak dipadatkan (.tar). Catatan : mengizinkan opsi ini berarti membuat cadangan yang telah dipadatkan lebih ringan, namun prosedur pencadangan awal akan jauh lebih lama dan membebani CPU.",
|
||||||
|
"global_settings_setting_nginx_redirect_to_https_help": "Alihkan permintaan HTTP ke HTTPs bawaan (JANGAN MATIKAN kecuali Anda benar-benar tahu apa yang Anda lakukan!)",
|
||||||
|
"group_user_not_in_group": "Pengguna {user} tidak ada dalam grup {group}",
|
||||||
|
"global_settings_setting_root_access_explain": "Pada sistem Linux, 'root' adalah admin mutlak. Dalam konteks YunoHost, masuk SSH sebagai 'root' secara langsung dinonaktifkan sesuai bawaan - kecuali dari jaringan lokal pada server. Anggota grup 'admin' dapat menggunakan perintah sudo untuk bertindak sebagai root dari baris perintah. Namun, akan sangat membantu jika memiliki kata sandi root (yang kuat) untuk melakukan debug pada sistem apabila dengan alasan tertentu admin biasa tidak dapat masuk lagi.",
|
||||||
|
"group_update_aliases": "Memperbarui alias untuk grup '{group}'",
|
||||||
|
"group_user_already_in_group": "Pengguna {user} sudah ada di grup {group}",
|
||||||
|
"hook_exec_failed": "Tidak dapat menjalankan skrip: {path}",
|
||||||
|
"group_no_change": "Tidak ada yang perlu dirubah pada grup '{group}'",
|
||||||
|
"invalid_number": "Harus berupa angka",
|
||||||
|
"log_domain_dns_push": "Mendorong rekaman DNS untuk domain '{}'",
|
||||||
|
"log_dyndns_subscribe": "Berlangganan ke subdomain YunoHost '{}'",
|
||||||
|
"log_link_to_failed_log": "Tidak dapat menyelesaikan operasi '{desc}'. Silakan memberi log lengkap operasi ini dengan cara <a href=\"#/tools/logs/{name}\">gklik di sini</a> agar mendapatkan bantuan",
|
||||||
|
"log_operation_unit_unclosed_properly": "Unit operasi belum ditutup dengan tepat",
|
||||||
|
"mail_forward_remove_failed": "tidak dapat menyingkirkan penerus surel '{mail}'",
|
||||||
|
"migration_0024_rebuild_python_venv_broken_app": "Melewatkan {app} karena virtualenv tidak dapat dibangun ulang dengan mudah pada aplikasi ini. Sebaliknya, Anda harus memperbaiki situasi ini dengan memaksa pemutakhiran aplikasi ini menggunakan `yunohost app upgrade --force {app}`.",
|
||||||
|
"migration_0021_general_warning": "Harap dicatat bahwa migrasi ini adalah operasi yang rumit. Tim YunoHost melakukan yang terbaik untuk meninjau dan mengujinya, namun migrasi tersebut mungkin dapat merusak bagian pada sistem atau aplikasinya.\n\nOleh karena itu, disarankan untuk:\n - Lakukan pencadangan data atau aplikasi penting apa pun. Informasi lebih lanjut di https://yunohost.org/backup;\n - Bersabarlah setelah menjalankan migrasi: Tergantung pada koneksi Internet dan perangkat keras Anda, mungkin diperlukan waktu hingga beberapa jam untuk memperbarui semuanya.",
|
||||||
|
"migration_0021_system_not_fully_up_to_date": "Sistem Anda belum sepenuhnya mutakhir. Harap lakukan pemutakhiran rutin sebelum menjalankan migrasi ke Bullseye.",
|
||||||
|
"migration_0024_rebuild_python_venv_disclaimer_base": "Setelah pemutakhiran ke Debian Bullseye, beberapa aplikasi Python perlu dibangun kembali sebagian agar dapat dikonversi ke versi Python baru yang dikirimkan bersama Debian (dalam istilah teknis: apa yang disebut 'virtualenv' perlu dibuat ulang). Sementara itu, aplikasi Python tersebut mungkin tidak berfungsi. YunoHost dapat mencoba membangun kembali virtualenv untuk beberapa di antaranya, seperti yang dijelaskan di bawah ini. Untuk aplikasi lain, atau jika upaya pembangunan kembali gagal, Anda perlu memaksakan pemutakhiran secara manual pada aplikasi tersebut.",
|
||||||
|
"migration_0027_not_bullseye": "Distribusi Debian saat ini bukanlah Bullseye! Jika Anda sudah menjalankan migrasi Bullseye -> Bookworm, maka galat ini merupakan gejala dari fakta bahwa prosedur migrasi tidak 100% berhasil (selain itu YunoHost akan menandainya sebagai komplet). Disarankan agar menyelidiki apa yang terjadi bersama dengan tim bantuan, yang memerlukan log migrasi **lengkap**, yang dapat ditemukan di Alat > Log pada webadmin.",
|
||||||
|
"migration_0027_general_warning": "Harap diingat bahwa migrasi ini adalah operasi yang rumit. Tim YunoHost melakukan yang terbaik untuk meninjau dan mengujinya, namun migrasi tersebut mungkin bisa merusak suatu bagian dari sistem atau aplikasinya.\n\nOleh karena itu, disarankan untuk:\n - Lakukan pencadangan data atau aplikasi penting apa pun. Informasi lebih lanjut di https://yunohost.org/backup;\n - Bersabarlah setelah meluncurkan migrasi: Tergantung pada koneksi Internet dan perangkat keras Anda, mungkin diperlukan waktu hingga beberapa jam agar semuanya dapat dimutakhirkan dengan tepat.",
|
||||||
|
"migration_0027_system_not_fully_up_to_date": "Sistem Anda belum sepenuhnya mutakhir. Harap melakukan pemutakhiran rutin sebelum menjalankan migrasi ke Bookworm.",
|
||||||
|
"migration_ldap_migration_failed_trying_to_rollback": "Tidak dapat bermigrasi… mencoba mengembalikan sistem seperti semula.",
|
||||||
|
"migrations_list_conflict_pending_done": "Anda tidak dapat menggunakan '--previous' dan '--done' secara bersamaan.",
|
||||||
|
"migrations_no_migrations_to_run": "Tidak ada migrasi yang harus dijalankan",
|
||||||
|
"global_settings_setting_passwordless_sudo": "Izinkan pengelola menggunakan 'sudo' tanpa mengetik ulang kata sandinya",
|
||||||
|
"group_cannot_edit_visitors": "Grup 'pengunjung' tidak dapat diedit secara manual. Ini adalah grup khusus yang mewakili pengunjung anonim",
|
||||||
|
"migration_0027_problematic_apps_warning": "Harap diperhatikan bahwa aplikasi terpasang yang mungkin bermasalah telah terdeteksi. Sepertinya aplikasi tersebut tidak dipasang dari katalog aplikasi YunoHost, atau tidak ditandai sebagai 'berfungsi'. Oleh karena itu, tidak ada jaminan bahwa aplikasi tersebut akan tetap berfungsi setelah pemutakhiran: {problematic_apps}",
|
||||||
|
"migrations_need_to_accept_disclaimer": "Untuk menjalankan migrasi {id}, Anda harus menerima pernyataan berikut:\n---\n{disclaimer}\n---\nJika Anda setuju untuk menjalankan migrasi, silakan jalankan kembali perintah dengan opsi '--accept-disclaimer'.",
|
||||||
|
"postinstall_low_rootfsspace": "Sistem pemberkasan root memiliki total ruang kurang dari 10 GB, yang cukup mengkhawatirkan! Kemungkinan besar Anda akan kehabisan ruang disket dengan sangat cepat! Disarankan agar memiliki setidaknya 16GB untuk sistem pemberkasan root. Jika Anda ingin memasang YunoHost meskipun ada peringatan ini, jalankan kembali pasca pemasangan dengan --force-diskspace",
|
||||||
|
"global_settings_setting_admin_strength_help": "Persyaratan ini hanya diterapkan saat mengawali atau mengubah kata sandi",
|
||||||
|
"global_settings_setting_nginx_compatibility_help": "Kompatibilas versus kompromi keamanan untuk server web NGINX. Mempengaruhi kerahasian (dan aspek terkait keamanan lainnya)",
|
||||||
|
"global_settings_setting_security_experimental_enabled_help": "Aktifkan fitur keamanan eksperimental (jangan mengaktifkan ini jika Anda tidak tahu apa yang Anda lakukan!)",
|
||||||
|
"global_settings_setting_ssowat_panel_overlay_enabled": "Aktifkan kotak pintasan portal kecil 'YunoHost' di aplikasi",
|
||||||
|
"global_settings_setting_user_strength": "Persyaratan kualitas kata sandi pengguna",
|
||||||
|
"global_settings_setting_user_strength_help": "Persyaratan ini hanya diterapkan saat mengawali atau mengubah kata sandi",
|
||||||
|
"global_settings_setting_webadmin_allowlist_enabled": "Aktifkan daftar IP Pengelelola web yang diizinkan",
|
||||||
|
"regenconf_up_to_date": "Konfigurasi sudah yang terbaru pada kategori '{category}'",
|
||||||
|
"global_settings_setting_smtp_relay_enabled_help": "Aktifkan relai SMTP yang akan digunakan untuk mengirim surel selain instansi yunohost ini. Berguna jika Anda berada dalam salah satu situasi ini: port 25 Anda diblokir oleh ISP atau penyedia VPS Anda, Anda memiliki IP residental yang terdaftar di DUHL, Anda tidak dapat mengkonfigurasi reverse DNS atau server ini tidak terekspos secara langsung di internet dan Anda ingin menggunakan yang lain untuk mengirim surel.",
|
||||||
|
"global_settings_setting_ssh_compatibility": "Kompatibilitas SSH",
|
||||||
|
"global_settings_setting_webadmin_allowlist_help": "Alamat IP diizinkan untuk mengakses webadmin. Notasi CIDR diperbolehkan.",
|
||||||
|
"global_settings_setting_ssh_port_help": "Port kurang dari 1024 lebih dianjurkan untuk mencegah upaya kudeta oleh layanan non-administrator pada mesin jarak jauh. Anda juga sebaiknya menghindari penggunaan port yang sudah digunakan, seperti 80 atau 443.",
|
||||||
|
"invalid_regex": "Regex tidak valid:'{regex}'",
|
||||||
|
"ip6tables_unavailable": "Anda tidak dapat menggunakan ip6tables di sini. Anda berada dalam sebuah penampungan atau kernel Anda yang tidak mendukungnya",
|
||||||
|
"global_settings_setting_ssh_compatibility_help": "Kompatibilitas versus kompromi keamanan untuk server SSH. Mempengaruhi kerahasiaan (dan aspek terkait keamanan lainnya). Lihat https://infosec.mozilla.org/guidelines/openssh untuk informasi lebih lanjut.",
|
||||||
|
"global_settings_setting_webadmin_allowlist": "Daftar IP pengelola web yang diizinkan",
|
||||||
|
"global_settings_setting_webadmin_allowlist_enabled_help": "Izinkan hanya beberapa IP untuk mengakses webadmin.",
|
||||||
|
"pattern_email": "Harus berupa alamat surel yang valid, tanpa simbol '+' (misalnya seseorang@example.com)",
|
||||||
|
"pattern_email_forward": "Harus berupa alamatsurel yang valid, simbol '+' masih diperbolehkan (misalnya seseorang+tag@example.com)",
|
||||||
|
"pattern_firstname": "Harus nama depan yang valid (minimal 3 karakter)",
|
||||||
|
"global_settings_setting_smtp_relay_enabled": "Aktifkan relai SMTP",
|
||||||
|
"migration_0024_rebuild_python_venv_disclaimer_ignored": "Virtualenvs tidak dapat dibangun kembali secara otomatis pada aplikasi tersebut. Anda perlu memaksakan pemutakhiran tersebut, yang dapat dilakukan dari baris perintah dengan: `yunohost app upgrade --force APP`: {ignored_apps}",
|
||||||
|
"pattern_mailbox_quota": "Harus seukuran dengan akhiran b/k/M/G/T atau 0 agar tidak memiliki kuota",
|
||||||
|
"pattern_username": "Harus berupa karakter huruf alfanumerik kecil dan garis bawah saja",
|
||||||
|
"invalid_shell": "Shell tidak valid: {shell}",
|
||||||
|
"global_settings_setting_smtp_relay_password": "Kata sandi relai SMTP",
|
||||||
|
"group_already_exist": "Grup {group} sudah ada",
|
||||||
|
"migration_ldap_can_not_backup_before_migration": "Pencadangan sistem tidak dapat diselesaikan sebelum migrasi gagal. Galat: {error}",
|
||||||
|
"migration_description_0026_new_admins_group": "Migrasi ke sistem 'multi admin' yang baru",
|
||||||
|
"migration_description_0025_global_settings_to_configpanel": "Migrasi nomenklatur pengaturan global lama ke nomenklatur baru dan modern",
|
||||||
|
"global_settings_setting_dns_exposure": "Versi IP yang perlu dipertimbangkan pada konfigurasi dan diagnosis DNS",
|
||||||
|
"unknown_main_domain_path": "Domain atau jalur pada '{app}' tidak diketahui. Anda perlu menentukan domain dan jalur agar dapat menentukan URL untuk perizinan.",
|
||||||
|
"migration_0023_postgresql_13_not_installed": "PostgreSQL 11 telah terpasang, tetapi PostgreSQL 13 tidak!? Sesuatu yang aneh mungkin terjadi pada sistem Anda :(…",
|
||||||
|
"migrations_skip_migration": "Melewatkan migrasi {id}…",
|
||||||
|
"regenconf_dry_pending_applying": "Memeriksa konfigurasi yang tertunda yang akan diterapkan pada kategori '{category}'…",
|
||||||
|
"group_already_exist_on_system_but_removing_it": "Grup {group} sudah ada di dalam grup sistem, tetapi YunoHost akan menyingkirkannya…",
|
||||||
|
"group_cannot_edit_primary_group": "Grup '{group}' tidak dapat diedit secara manual. Ini adalah grup utama yang dimaksudkan untuk menampung hanya satu pengguna tertentu.",
|
||||||
|
"group_mailalias_add": "Alias email '{mail}' akan ditambahkan ke grup '{group}'",
|
||||||
|
"group_user_add": "Pengguna '{user}' akan ditambahkan ke grup '{group}'",
|
||||||
|
"group_user_remove": "Pengguna '{user}' akan disingkirkan dari grup '{group}'",
|
||||||
|
"hook_exec_not_terminated": "Skrip tidak selesai dengan tepat: {path}",
|
||||||
|
"hook_json_return_error": "Tidak dapat membaca jawaban dari pengait {path}. Galat: {msg}. Konten mentah: {raw_content}",
|
||||||
|
"hook_list_by_invalid": "Properti ini tidak dapat digunakan untuk mencantumkan pengait",
|
||||||
|
"hook_name_unknown": "Nama pengait '{name}' tidak diketahui",
|
||||||
|
"ldap_server_is_down_restart_it": "Layanan LDAP tidak aktif, mencoba memulai ulang…",
|
||||||
|
"log_dyndns_update": "Perbarui IP yang terkait dengan subdomain YunoHost Anda '{}'",
|
||||||
|
"log_permission_url": "Perbarui URL terkait izin '{}'",
|
||||||
|
"log_remove_on_failed_install": "Menyingkirkan '{}' setelah instalasi gagal",
|
||||||
|
"log_resource_snippet": "Menyediakan/Meniadakan/memperbarui sumber daya",
|
||||||
|
"log_tools_postinstall": "Pasca pemasangan server YunoHost Anda",
|
||||||
|
"migration_0021_modified_files": "Harap diperhatikan bahwa berkas berikut ternyata telah dimodifikasi secara manual dan mungkin ditimpa setelah peningkatan: {manually_modified_files}",
|
||||||
|
"migration_0021_not_buster2": "Distribusi Debian saat ini bukanlah Buster! Jika Anda sudah menjalankan migrasi Buster -> Bullseye, maka galat ini merupakan gejala dari fakta bahwa prosedur migrasi tidak berhasil 100% (sebaliknya YunoHost akan menandainya sebagai komplet). Disarankan agar menyelidiki apa yang terjadi bersama dengan tim bantuan, yang memerlukan log migrasi **lengkap**, yang dapat ditemukan pada Alat > Log dalam webadmin.",
|
||||||
|
"migration_0021_not_enough_free_space": "Ruang kosong cukup sedikit di /var/! Anda harus memiliki setidaknya 1 GB ruang kosong untuk menjalankan migrasi ini.",
|
||||||
|
"migration_0021_patch_yunohost_conflicts": "Menerapkan tambalan untuk menanggulangi isu konflik…",
|
||||||
|
"migration_0021_patching_sources_list": "Menambal sources.lists tersebut…",
|
||||||
|
"migration_0021_still_on_buster_after_main_upgrade": "Ada yang tidak sesuai saat pemutakhiran utama, sistem tampaknya masih menggunakan Debian Buster",
|
||||||
|
"migration_0021_problematic_apps_warning": "Harap diperhatikan bahwa aplikasi terpasang yang mungkin bermasalah telah terdeteksi. Sepertinya aplikasi tersebut tidak dipasang dari katalog aplikasi YunoHost, atau tidak ditandai sebagai 'berfungsi'. Oleh karena itu, tidak ada jaminan bahwa aplikasi tersebut akan tetap berfungsi setelah pemutakhiran: {problematic_apps}",
|
||||||
|
"migration_0023_not_enough_space": "Sediakan ruang yang cukup di {path} untuk menjalankan migrasi.",
|
||||||
|
"migration_0024_rebuild_python_venv_disclaimer_rebuild": "Membangun kembali virtualenv akan dicoba pada aplikasi berikut (NB: pengoperasiannya mungkin memerlukan beberapa waktu!): {rebuild_apps}",
|
||||||
|
"migration_0024_rebuild_python_venv_failed": "Gagal membangun kembali virtualenv Python pada {app}. Aplikasi mungkin tidak berfungsi selama masalah tersebut belum diselesaikan. Anda harus memperbaiki situasi ini dengan memaksa pemutakhiran aplikasi ini menggunakan `yunohost app upgrade --force {app}`.",
|
||||||
|
"migration_0024_rebuild_python_venv_in_progress": "Sekarang mencoba membangun kembali virtualenv Python pada `{app}`",
|
||||||
|
"migration_0027_not_enough_free_space": "Ruang kosong cukup sedikit di /var/! Anda harus memiliki setidaknya 1 GB ruang kosong untuk menjalankan migrasi ini.",
|
||||||
|
"migration_0027_patch_yunohost_conflicts": "Menerapkan tambalan untuk menanggulangi isu konflik…",
|
||||||
|
"migrations_no_such_migration": "Tidak ada migrasi yang disebut '{id}'",
|
||||||
|
"migration_0027_cleaning_up": "Membersihkan cache dan paket yang sudah tidak berguna…",
|
||||||
|
"migration_0027_delayed_api_restart": "API YunoHost akan otomatis diulangi dalam 15 detik. Ini mungkin tidak tersedia selama beberapa detik, dan kemudian Anda harus masuk lagi.",
|
||||||
|
"migration_0027_main_upgrade": "Memulai pemutakhiran utama…",
|
||||||
|
"migration_0027_modified_files": "Harap diperhatikan bahwa berkas berikut ternyata dimodifikasi secara manual dan mungkin ditimpa setelah pemutakhiran: {manually_modified_files}",
|
||||||
|
"migration_0027_patching_sources_list": "Menambal berkas source.lists…",
|
||||||
|
"migration_ldap_rollback_success": "Mengembalikan sistem seperti semula.",
|
||||||
|
"migrations_already_ran": "Migrasi tersebut sudah selesai: {ids}",
|
||||||
|
"migrations_loading_migration": "Memuat migrasi {id}…",
|
||||||
|
"migrations_to_be_ran_manually": "Migrasi {id} harus dijalankan secara manual. Silakan buka Alat → Migrasi di halaman webadmin, atau jalankan `yunohost tools migrans run`.",
|
||||||
|
"pattern_backup_archive_name": "Harus berupa nama berkas yang valid dengan maksimal 30 karakter, alfanumerik dan karakter -_. saja",
|
||||||
|
"pattern_fullname": "Harus berupa nama lengkap yang valid (minimal 3 karakter)",
|
||||||
|
"permission_already_up_to_date": "Izin tidak akan diperbarui karena permintaan menambahkan/menyingkirkan sudah sesuai dengan kondisi saat ini.",
|
||||||
|
"regenconf_need_to_explicitly_specify_ssh": "Konfigurasi ssh telah dimodifikasi secara manual, namun Anda perlu secara eksplisit menentukan kategori 'ssh' dengan --force agar menerapkan perubahan yang sebenarnya.",
|
||||||
|
"regenconf_pending_applying": "Menerapkan konfigurasi yang tertunda pada kategori '{category}'…",
|
||||||
|
"regenconf_would_be_updated": "Konfigurasi akan diperbarui pada kategori '{category}'",
|
||||||
|
"regex_incompatible_with_tile": "/!\\ Pemaket! Perizinan '{permission}' memiliki show_tile yang diatur menjadi 'true' dan oleh karena itu Anda tidak dapat menentukan URL regex sebagai URL utama",
|
||||||
|
"restore_extracting": "Mengekstrak berkas yang diperlukan dari arsip…",
|
||||||
|
"restore_hook_unavailable": "Skrip pemulihan pada '{part}' tidak tersedia pada sistem Anda dan juga tidak ada di dalam arsip",
|
||||||
|
"restore_may_be_not_enough_disk_space": "Sistem Anda tampaknya tidak memiliki cukup ruang (bebas: {free_space} B, ruang yang diperlukan: {needed_space} B, batas keamanan: {margin} B)",
|
||||||
|
"service_description_redis-server": "Basis data khusus yang digunakan untuk akses data cepat, antrian tugas, dan komunikasi antar program",
|
||||||
|
"update_apt_cache_warning": "Ada yang tidak sesuai saat memperbarui cache APT (manajer paket Debian). Berikut ini adalah kumpulan baris source.list, yang mungkin membantu mengidentifikasi baris yang bermasalah:\n{sourceslist}",
|
||||||
|
"user_import_missing_columns": "Kehilangan kolom berikut: {columns}",
|
||||||
|
"user_import_nothing_to_do": "Tidak ada pengguna yang perlu diimpor",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains": "Domain yang digunakan sebagai MX sekunder",
|
||||||
|
"global_settings_setting_smtp_backup_mx_domains_help": "Izinkan server ini digunakan sebagai domain MX *sekunder* cadangan pada domain yang terdaftar. Ini berarti bahwa jika MX utama untuk domain tersebut tidak dapat dijangkau (misalnya karena gangguan), surel akan tetap dikirim ke server ini, yang akan menyimpannya selama maksimal 20 hari dan mencoba meneruskannya ke tujuan yang sebenarnya setelah kembali aktif. Beberapa domain dapat disediakan, dipisahkan dengan koma.",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted": "Daftar surel yang diperbolehkan sebagai MX cadangan SMTP",
|
||||||
|
"diagnosis_rfkill_wifi": "Kartu Wi-Fi dinonaktifkan dan peringatan sistem mungkin akan mencegah pemasangan aplikasi",
|
||||||
|
"diagnosis_rfkill_wifi_details": "Peringatan ini muncul di banyak keluaran perintah, sehingga merusak beberapa aplikasi. Biasanya Anda diminta untuk menentukan kode negara dengan perintah <code>sudo raspi-config</code>. Galat yang muncul:<br>{rfkill_wifi_error}",
|
||||||
|
"global_settings_setting_smtp_backup_mx_emails_whitelisted_help": "Bila digunakan sebagai MX sekunder, daftar lengkap alamat surel penerima yang diizinkan harus disediakan (sebaliknya surel akan ditolak dan dibuang). Beberapa alamat dapat diberikan, dipisahkan dengan koma."
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
"app_not_installed": "{app} не найдено в списке установленных приложений: {all_apps}",
|
"app_not_installed": "{app} не найдено в списке установленных приложений: {all_apps}",
|
||||||
"app_not_properly_removed": "{app} удалены неправильно",
|
"app_not_properly_removed": "{app} удалены неправильно",
|
||||||
"app_removed": "{app} удалено",
|
"app_removed": "{app} удалено",
|
||||||
"app_requirements_checking": "Проверка необходимых пакетов для {app}…",
|
"app_requirements_checking": "Проверка зависимостей для {app}…",
|
||||||
"app_sources_fetch_failed": "Невозможно получить исходные файлы, проверьте правильность URL?",
|
"app_sources_fetch_failed": "Невозможно получить исходные файлы, проверьте правильность URL?",
|
||||||
"app_unknown": "Неизвестное приложение",
|
"app_unknown": "Неизвестное приложение",
|
||||||
"app_upgrade_app_name": "Обновление {app}…",
|
"app_upgrade_app_name": "Обновление {app}…",
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
"ask_new_domain": "Новый домен",
|
"ask_new_domain": "Новый домен",
|
||||||
"ask_new_path": "Новый путь",
|
"ask_new_path": "Новый путь",
|
||||||
"ask_password": "Пароль",
|
"ask_password": "Пароль",
|
||||||
"app_remove_after_failed_install": "Удаление приложения после сбоя установки…",
|
"app_remove_after_failed_install": "Удаление приложения после ошибки установки…",
|
||||||
"app_upgrade_script_failed": "Внутри скрипта обновления приложения произошла ошибка",
|
"app_upgrade_script_failed": "Внутри скрипта обновления приложения произошла ошибка",
|
||||||
"upnp_disabled": "UPnP отключен",
|
"upnp_disabled": "UPnP отключен",
|
||||||
"app_manifest_install_ask_domain": "Выберите домен, в котором должно быть установлено это приложение",
|
"app_manifest_install_ask_domain": "Выберите домен, в котором должно быть установлено это приложение",
|
||||||
|
@ -76,13 +76,13 @@
|
||||||
"apps_catalog_init_success": "Система каталога приложений инициализирована!",
|
"apps_catalog_init_success": "Система каталога приложений инициализирована!",
|
||||||
"backup_abstract_method": "Этот метод резервного копирования еще не реализован",
|
"backup_abstract_method": "Этот метод резервного копирования еще не реализован",
|
||||||
"backup_actually_backuping": "Создание резервного архива из собранных файлов…",
|
"backup_actually_backuping": "Создание резервного архива из собранных файлов…",
|
||||||
"backup_applying_method_custom": "Вызов пользовательского метода резервного копирования {method}'…",
|
"backup_applying_method_custom": "Вызов пользовательского метода резервного копирования «{method}»…",
|
||||||
"backup_archive_app_not_found": "Не удалось найти {app} в резервной копии",
|
"backup_archive_app_not_found": "Не удалось найти {app} в резервной копии",
|
||||||
"backup_applying_method_tar": "Создание резервной копии в TAR-архиве…",
|
"backup_applying_method_tar": "Создание резервной копии в TAR-архиве…",
|
||||||
"backup_archive_broken_link": "Не удалось получить доступ к резервной копии (неправильная ссылка {path})",
|
"backup_archive_broken_link": "Не удалось получить доступ к резервной копии (неправильная ссылка {path})",
|
||||||
"apps_catalog_failed_to_download": "Невозможно загрузить каталог приложений {apps_catalog}: {error}",
|
"apps_catalog_failed_to_download": "Невозможно загрузить каталог приложений {apps_catalog}: {error}",
|
||||||
"apps_catalog_obsolete_cache": "Кэш каталога приложений пуст или устарел.",
|
"apps_catalog_obsolete_cache": "Кэш каталога приложений пуст или устарел.",
|
||||||
"backup_archive_cant_retrieve_info_json": "Не удалось загрузить информацию об архиве '{archive}'… info.json не может быть получен (или не является корректным json).",
|
"backup_archive_cant_retrieve_info_json": "Не удалось загрузить информацию об архиве «{archive}»… Файл info.json не может быть получен (или не является корректным json).",
|
||||||
"app_packaging_format_not_supported": "Это приложение не может быть установлено, поскольку его формат не поддерживается вашей версией YunoHost. Возможно, вам следует обновить систему.",
|
"app_packaging_format_not_supported": "Это приложение не может быть установлено, поскольку его формат не поддерживается вашей версией YunoHost. Возможно, вам следует обновить систему.",
|
||||||
"app_restore_failed": "Не удалось восстановить {app}: {error}",
|
"app_restore_failed": "Не удалось восстановить {app}: {error}",
|
||||||
"app_restore_script_failed": "Произошла ошибка внутри сценария восстановления приложения",
|
"app_restore_script_failed": "Произошла ошибка внутри сценария восстановления приложения",
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
"app_start_backup": "Сбор файлов для резервного копирования {app}…",
|
"app_start_backup": "Сбор файлов для резервного копирования {app}…",
|
||||||
"app_start_install": "Устанавливается {app}…",
|
"app_start_install": "Устанавливается {app}…",
|
||||||
"backup_app_failed": "Не удалось создать резервную копию {app}",
|
"backup_app_failed": "Не удалось создать резервную копию {app}",
|
||||||
"backup_archive_name_exists": "Резервная копия с таким именем уже существует.",
|
"backup_archive_name_exists": "Резервная копия с именем «{name}» уже существует.",
|
||||||
"backup_archive_name_unknown": "Неизвестный локальный архив резервного копирования с именем '{name}'",
|
"backup_archive_name_unknown": "Неизвестный локальный архив резервного копирования с именем '{name}'",
|
||||||
"backup_archive_open_failed": "Не удалось открыть архив резервной копии",
|
"backup_archive_open_failed": "Не удалось открыть архив резервной копии",
|
||||||
"backup_archive_corrupted": "Похоже, что архив резервной копии '{archive}' поврежден : {error}",
|
"backup_archive_corrupted": "Похоже, что архив резервной копии '{archive}' поврежден : {error}",
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
"config_no_panel": "Панель конфигурации не найдена.",
|
"config_no_panel": "Панель конфигурации не найдена.",
|
||||||
"danger": "Опасно:",
|
"danger": "Опасно:",
|
||||||
"certmanager_warning_subdomain_dns_record": "Субдомен '{subdomain}' не соответствует IP-адресу основного домена '{domain}'. Некоторые функции будут недоступны, пока вы не исправите это и не сгенерируете сертификат снова.",
|
"certmanager_warning_subdomain_dns_record": "Субдомен '{subdomain}' не соответствует IP-адресу основного домена '{domain}'. Некоторые функции будут недоступны, пока вы не исправите это и не сгенерируете сертификат снова.",
|
||||||
"app_argument_password_no_default": "Ошибка при парсинге аргумента пароля '{name}': аргумент пароля не может иметь значение по умолчанию по причинам безопасности",
|
"app_argument_password_no_default": "Ошибка при парсинге аргумента пароля «{name}»: аргумент пароля не может иметь значение по умолчанию по причинам безопасности",
|
||||||
"custom_app_url_required": "Вы должны указать URL для обновления вашего пользовательского приложения {app}",
|
"custom_app_url_required": "Вы должны указать URL для обновления вашего пользовательского приложения {app}",
|
||||||
"backup_creation_failed": "Не удалось создать резервную копию",
|
"backup_creation_failed": "Не удалось создать резервную копию",
|
||||||
"backup_csv_addition_failed": "Не удалось добавить файлы для резервного копирования в CSV-файл",
|
"backup_csv_addition_failed": "Не удалось добавить файлы для резервного копирования в CSV-файл",
|
||||||
|
@ -136,8 +136,8 @@
|
||||||
"diagnosis_apps_issue": "Обнаружена проблема для приложения {app}",
|
"diagnosis_apps_issue": "Обнаружена проблема для приложения {app}",
|
||||||
"diagnosis_apps_not_in_app_catalog": "Этого приложения нет в каталоге приложений YunoHost. Если оно было там раньше, а теперь удалено, вам стоит подумать об удалении этого приложения, так как оно больше не получит обновлений и может нарушить целостность и безопасность вашей системы.",
|
"diagnosis_apps_not_in_app_catalog": "Этого приложения нет в каталоге приложений YunoHost. Если оно было там раньше, а теперь удалено, вам стоит подумать об удалении этого приложения, так как оно больше не получит обновлений и может нарушить целостность и безопасность вашей системы.",
|
||||||
"diagnosis_apps_deprecated_practices": "Установленная версия этого приложения все еще использует некоторые устаревшие пакеты. Вам стоит подумать об обновлении.",
|
"diagnosis_apps_deprecated_practices": "Установленная версия этого приложения все еще использует некоторые устаревшие пакеты. Вам стоит подумать об обновлении.",
|
||||||
"additional_urls_already_added": "Этот URL '{url}' уже добавлен в дополнительный URL для разрешения '{permission}'",
|
"additional_urls_already_added": "Этот URL «{url}» уже добавлен в дополнительный URL для разрешения «{permission}»",
|
||||||
"additional_urls_already_removed": "Этот URL '{url}' уже удален из дополнительных URL для разрешения '{permission}'",
|
"additional_urls_already_removed": "Этот URL «{url}» уже удален из дополнительных URL для разрешения «{permission}»",
|
||||||
"app_action_cannot_be_ran_because_required_services_down": "Для выполнения этого действия должны быть запущены следующие службы: {services}. Попробуйте перезапустить их, чтобы продолжить (и, возможно, выяснить, почему они не работают).",
|
"app_action_cannot_be_ran_because_required_services_down": "Для выполнения этого действия должны быть запущены следующие службы: {services}. Попробуйте перезапустить их, чтобы продолжить (и, возможно, выяснить, почему они не работают).",
|
||||||
"app_unsupported_remote_type": "Неподдерживаемый удаленный тип, используемый для приложения",
|
"app_unsupported_remote_type": "Неподдерживаемый удаленный тип, используемый для приложения",
|
||||||
"backup_archive_system_part_not_available": "Системная часть '{part}' недоступна в этой резервной копии",
|
"backup_archive_system_part_not_available": "Системная часть '{part}' недоступна в этой резервной копии",
|
||||||
|
@ -166,7 +166,7 @@
|
||||||
"diagnosis_description_services": "Проверка статусов сервисов",
|
"diagnosis_description_services": "Проверка статусов сервисов",
|
||||||
"config_validate_color": "Должен быть правильный hex цвета RGB",
|
"config_validate_color": "Должен быть правильный hex цвета RGB",
|
||||||
"diagnosis_basesystem_hardware": "Аппаратная архитектура сервера – {virt} {arch}",
|
"diagnosis_basesystem_hardware": "Аппаратная архитектура сервера – {virt} {arch}",
|
||||||
"certmanager_acme_not_configured_for_domain": "Задача ACME не может быть запущена для {domain} прямо сейчас, потому что в его nginx conf отсутствует соответствующий фрагмент кода… Пожалуйста, убедитесь, что конфигурация вашего nginx обновлена, используя 'yunohost tools regen-conf nginx --dry-run --with-diff'.",
|
"certmanager_acme_not_configured_for_domain": "Задача ACME не может быть запущена для {domain} прямо сейчас, потому что в его конфигурации nginx отсутствует соответствующий фрагмент кода… Пожалуйста, убедитесь, что Ваша конфигурация nginx обновлена, используя «yunohost tools regen-conf nginx --dry-run --with-diff».",
|
||||||
"diagnosis_basesystem_ynh_single_version": "{package} версия: {version} ({repo})",
|
"diagnosis_basesystem_ynh_single_version": "{package} версия: {version} ({repo})",
|
||||||
"diagnosis_description_mail": "Электронная почта",
|
"diagnosis_description_mail": "Электронная почта",
|
||||||
"diagnosis_basesystem_kernel": "Версия ядра Linux на сервере {kernel_version}",
|
"diagnosis_basesystem_kernel": "Версия ядра Linux на сервере {kernel_version}",
|
||||||
|
@ -328,5 +328,36 @@
|
||||||
"global_settings_setting_smtp_allow_ipv6_help": "Разрешить использование IPv6 для получения и отправки почты",
|
"global_settings_setting_smtp_allow_ipv6_help": "Разрешить использование IPv6 для получения и отправки почты",
|
||||||
"admins": "Администраторы",
|
"admins": "Администраторы",
|
||||||
"all_users": "Все пользователи YunoHost",
|
"all_users": "Все пользователи YunoHost",
|
||||||
"app_action_failed": "Не удалось выполнить действие {action} для приложения {app}"
|
"app_action_failed": "Не удалось выполнить действие {action} для приложения {app}",
|
||||||
|
"app_manifest_install_ask_init_main_permission": "Кто должен иметь доступ к этому приложению? (Это может быть изменено позже)",
|
||||||
|
"app_arch_not_supported": "Это приложение может быть установлено только на архитектуры {required}, но архитектура вашего сервер - {current}",
|
||||||
|
"app_manifest_install_ask_init_admin_permission": "Кто должен иметь доступ к функциям для администраторов этого приложения? (Это может быть изменено позже)",
|
||||||
|
"app_change_url_script_failed": "Произошла ошибка внутри скрипта смены URL",
|
||||||
|
"app_corrupt_source": "YunoHost смог скачать материал «{source_id}» ({url}) для {app}, но материал не соотвествует с ожидаемой контрольной суммой. Это может означать, что на ваше сервере произошла временная сетевая ошибка, ИЛИ материал был каким-либо образом изменён сопровождающим главной ветки (или злоумышленником?) и упаковщикам YunoHost нужно выяснить и, возможно, обновить манифест, чтобы применить изменения.\n Ожидаемая контрольная сумма sha256: {expected_sha256}\n Полученная контрольная сумма sha256: {computed_sha256}\n Размер скачанного файла: {size}",
|
||||||
|
"app_not_enough_ram": "Это приложение требует {required} ОЗУ для установки/обновления, но сейчас доступно только {current}.",
|
||||||
|
"app_change_url_failed": "Невозможно изменить URL для {app}: {error}",
|
||||||
|
"app_not_enough_disk": "Это приложение требует {required} свободного места.",
|
||||||
|
"app_change_url_require_full_domain": "{app} не может быть перемещено на данный URL, потому что оно требует весь домен (т.е., путь - /)",
|
||||||
|
"app_failed_to_download_asset": "Не удалось скачать материал «{source_id}» ({url}) для {app}: {out}",
|
||||||
|
"app_failed_to_upgrade_but_continue": "Не удалось обновить приложение {failed_app}, обновления продолжаются, как запрошено. Выполните «yunohost log show {operation_logger_name}», чтобы увидеть журнал ошибки",
|
||||||
|
"app_not_upgraded_broken_system": "Не удалось обновить приложение «{failed_app}», система находится в сломанном состоянии, обновления следующих приложений были отменены: {apps}",
|
||||||
|
"ask_dyndns_recovery_password_explain_unavailable": "Этот домен DynDNS уже зарегистрирован. Если Вы — личность, которая изначально зарегистрировала этот домен, Вы можете ввести пароль, чтобы заново занять этот домен.",
|
||||||
|
"ask_dyndns_recovery_password": "Пароль восстановления DynDNS",
|
||||||
|
"certmanager_cert_install_failed": "Не удалась установка сертификата Let's Encrypt для {domains}",
|
||||||
|
"certmanager_cert_install_failed_selfsigned": "Установка само-подписанного сертификата для {domains} не удалась",
|
||||||
|
"backup_hook_unknown": "Хук резервного копирования «{hook}» неизвестен",
|
||||||
|
"backup_no_uncompress_archive_dir": "Такой несжатой директории не существует",
|
||||||
|
"backup_unable_to_organize_files": "Невозможно использовать быстрый метод организации файлов в архиве",
|
||||||
|
"app_resource_failed": "Установка, удаление или обновление ресурсов {app} провалилась: {error}",
|
||||||
|
"ask_dyndns_recovery_password_explain": "Пожалуйста, выберите пароль восстановления для Вашего домена DynDNS, для случая, если Вам понадобится сбросить его позже.",
|
||||||
|
"ask_dyndns_recovery_password_explain_during_unsubscribe": "Пожалуйста, выберите пароль восстановления для Вашего домена DynDNS.",
|
||||||
|
"app_not_upgraded_broken_system_continue": "Приложение «{failed_app}» не смогло обновиться и сломало систему (так что --continue-on-failure игнорируется), и, в свою очередь, обновления других приложений были отменены: {apps}",
|
||||||
|
"backup_output_symlink_dir_broken": "Директория «{path}» Вашего архива — сломанная символьная ссылка. Может быть, Вы забыли смонтировать или подключить устройство, на которое она ссылается.",
|
||||||
|
"ask_fullname": "Полное имя",
|
||||||
|
"ask_admin_username": "Имя пользователя администратора",
|
||||||
|
"backup_running_hooks": "Выполняются хуки резервного копирования…",
|
||||||
|
"app_yunohost_version_not_supported": "Это приложение требует YunoHost версии {required} или выше, но сейчас установлена версия {current}",
|
||||||
|
"apps_failed_to_upgrade": "Не удалось обновить данные приложения:{apps}",
|
||||||
|
"apps_failed_to_upgrade_line": "\n * {app_id} (чтобы увидеть соответствующий журнал, выполните «yunohost log show {operation_logger_name}»)",
|
||||||
|
"ask_admin_fullname": "Полное имя администратора"
|
||||||
}
|
}
|
|
@ -265,5 +265,19 @@
|
||||||
"service_description_rspamd": "Filtruje spam a iné funkcie týkajúce sa e-mailu",
|
"service_description_rspamd": "Filtruje spam a iné funkcie týkajúce sa e-mailu",
|
||||||
"log_letsencrypt_cert_renew": "Obnoviť '{}' certifikát Let's Encrypt",
|
"log_letsencrypt_cert_renew": "Obnoviť '{}' certifikát Let's Encrypt",
|
||||||
"domain_config_cert_summary_selfsigned": "UPOZORNENIE: Aktuálny certifikát je vlastnoručne podpísaný. Prehliadače budú návštevníkom zobrazovať strašidelné varovanie!",
|
"domain_config_cert_summary_selfsigned": "UPOZORNENIE: Aktuálny certifikát je vlastnoručne podpísaný. Prehliadače budú návštevníkom zobrazovať strašidelné varovanie!",
|
||||||
"global_settings_setting_ssowat_panel_overlay_enabled": "Povoliť malú štvorcovú ikonu portálu „YunoHost“ na aplikáciach"
|
"global_settings_setting_ssowat_panel_overlay_enabled": "Povoliť malú štvorcovú ikonu portálu „YunoHost“ na aplikáciach",
|
||||||
|
"domain_config_mail_out": "Odchádzajúce e-maily",
|
||||||
|
"domain_config_default_app": "Predvolená aplikácia",
|
||||||
|
"domain_config_xmpp_help": "Pozor: niektoré funkcie XMPP vyžadujú aktualizáciu vašich DNS záznamov a obnovenie Lets Encrypt certifikátu pred tým, ako je ich možné zapnúť",
|
||||||
|
"domain_config_default_app_help": "Návštevníci budú pri návšteve tejto domény automaticky presmerovaní na túto doménu. Ak nenastavíte žiadnu aplikáciu, zobrazí sa stránka s prihlasovacím formulárom na portál.",
|
||||||
|
"registrar_infos": "Informácie o registrátorovi",
|
||||||
|
"domain_dns_registrar_managed_in_parent_domain": "Táto doména je subdoména {parent_domain_link}. Nastavenie DNS registrátora je spravovaná v konfiguračnom paneli {parent_domain}.",
|
||||||
|
"log_letsencrypt_cert_install": "Inštalovať certifikát Let's Encrypt na doménu '{}'",
|
||||||
|
"domain_config_cert_no_checks": "Ignorovať kontroly diagnostiky",
|
||||||
|
"domain_config_cert_install": "Nainštalovať certifikát Let's Encrypt",
|
||||||
|
"domain_config_mail_in": "Prichádzajúce e-maily",
|
||||||
|
"domain_config_cert_summary": "Stav certifikátu",
|
||||||
|
"domain_config_xmpp": "Krátke správy (XMPP)",
|
||||||
|
"log_app_makedefault": "Nastaviť '{}' ako predvolenú aplikáciu",
|
||||||
|
"domain_config_cert_renew_help": "Certifikát bude automaticky obnovený po 15 dňoch platnosti. Ak chcete, môžete ho obnoviť aj ručne. (Neodporúča sa)."
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"password_too_simple_1": "Şifre en az 8 karakter uzunluğunda olmalı",
|
"password_too_simple_1": "Şifre en az 8 karakter uzunluğunda olmalı",
|
||||||
"action_invalid": "Geçersiz işlem '{action}'",
|
"action_invalid": "Geçersiz işlem '{action}'",
|
||||||
"admin_password": "Yönetici şifresi",
|
"admin_password": "Yönetici parolası",
|
||||||
"already_up_to_date": "Yapılacak yeni bir şey yok. Her şey zaten güncel.",
|
"already_up_to_date": "Yapılacak yeni bir şey yok. Her şey zaten güncel.",
|
||||||
"app_action_broke_system": "Bu işlem bazı hizmetleri bozmuş olabilir: {services}",
|
"app_action_broke_system": "Bu işlem bazı hizmetleri bozmuş olabilir: {services}",
|
||||||
"good_practices_about_user_password": "Şimdi yeni bir kullanıcı şifresi tanımlamak üzeresiniz. Parola en az 8 karakter uzunluğunda olmalıdır - ancak daha uzun bir parola (yani bir parola) ve/veya çeşitli karakterler (büyük harf, küçük harf, rakamlar ve özel karakterler) daha iyidir.",
|
"good_practices_about_user_password": "Şimdi yeni bir kullanıcı şifresi tanımlamak üzeresiniz. Parola en az 8 karakter uzunluğunda olmalıdır - ancak daha uzun bir parola (yani bir parola) ve/veya çeşitli karakterler (büyük harf, küçük harf, rakamlar ve özel karakterler) daha iyidir.",
|
||||||
|
@ -20,5 +20,16 @@
|
||||||
"app_change_url_failed": "{app}: {error} için url değiştirilemedi",
|
"app_change_url_failed": "{app}: {error} için url değiştirilemedi",
|
||||||
"app_argument_required": "'{name}' değeri gerekli",
|
"app_argument_required": "'{name}' değeri gerekli",
|
||||||
"app_argument_invalid": "'{name}': {error} için geçerli bir değer giriniz",
|
"app_argument_invalid": "'{name}': {error} için geçerli bir değer giriniz",
|
||||||
"app_argument_password_no_default": "'{name}': çözümlenirken bir hata meydana geldi. Parola argümanı güvenlik nedeniyle varsayılan değer alamaz"
|
"app_argument_password_no_default": "'{name}': çözümlenirken bir hata meydana geldi. Parola argümanı güvenlik nedeniyle varsayılan değer alamaz",
|
||||||
|
"app_failed_to_download_asset": "{app} uygulaması için {source_id}{url} adresinden indirme işlemi sağlanamadı: {out}",
|
||||||
|
"app_extraction_failed": "Kurulum dosyaları çıkarılamadı",
|
||||||
|
"app_change_url_require_full_domain": "{app} bu yeni URL'ye taşınamaz. Çünkü ana etki alanı gerekli (Yani path = / olmalı )",
|
||||||
|
"app_change_url_script_failed": "URL değiştirme betiğinde bir hata oluştu",
|
||||||
|
"app_change_url_success": "{app} URL artık {domain}{path}",
|
||||||
|
"app_config_unable_to_apply": "Yapılandırma paneli değerleri uygulanamadı.",
|
||||||
|
"app_config_unable_to_read": "Yapılandırma paneli değerleri okunamadı.",
|
||||||
|
"app_change_url_no_script": "{app_name} uygulaması henüz URL değişikliğini desteklemiyor. Paket yükseltmeniz gerekebilir.",
|
||||||
|
"app_change_url_identical_domains": "('{domain}{path}') Eski ve yeni alan adının veya URL adresler aynı.Şu anda yapacak bir şey bulunmuyor.",
|
||||||
|
"app_corrupt_source": "YunoHost, {app} için '{source_id}' ({url}) adresinden indirebildi, ancak varlık olması gereken yapılandırmalarla eşleşmiyor. Bu, sunucunuzda geçici bir ağ arızası meydana geldiği veya varlığın bir şekilde yayın yapılan veri sağlacıyısı (veya kötü niyetli bir kişi?) tarafından değiştirildiği ve YunoHost yapımcılarının araştırması ve belki de bu değişikliği dikkate almak için uygulama bildirimini güncellemesi gerektiği anlamına gelebilir.\n Beklenen sha256 sağlama toplamı: {expected_sha256}\n İndirilen sha256 sağlama toplamı: {computed_sha256}\n İndirilen dosya boyutu: {size}",
|
||||||
|
"app_failed_to_upgrade_but_continue": "{failed_app} uygulaması yükseltilirken başarısız oldu. Sıradaki güncellemeler devam ediyor. Konu ile ilgili hata kayıtlarını görüntülemek için 'yunohost log show {operation_logger_name}' komutunu çalıştırın"
|
||||||
}
|
}
|
|
@ -32,6 +32,7 @@ def find_expected_string_keys():
|
||||||
python_files = glob.glob(ROOT + "src/*.py")
|
python_files = glob.glob(ROOT + "src/*.py")
|
||||||
python_files.extend(glob.glob(ROOT + "src/utils/*.py"))
|
python_files.extend(glob.glob(ROOT + "src/utils/*.py"))
|
||||||
python_files.extend(glob.glob(ROOT + "src/migrations/*.py"))
|
python_files.extend(glob.glob(ROOT + "src/migrations/*.py"))
|
||||||
|
python_files.extend(glob.glob(ROOT + "src/migrations/*.py.disabled"))
|
||||||
python_files.extend(glob.glob(ROOT + "src/authenticators/*.py"))
|
python_files.extend(glob.glob(ROOT + "src/authenticators/*.py"))
|
||||||
python_files.extend(glob.glob(ROOT + "src/diagnosers/*.py"))
|
python_files.extend(glob.glob(ROOT + "src/diagnosers/*.py"))
|
||||||
python_files.append(ROOT + "bin/yunohost")
|
python_files.append(ROOT + "bin/yunohost")
|
||||||
|
@ -75,6 +76,9 @@ def find_expected_string_keys():
|
||||||
continue
|
continue
|
||||||
yield "migration_description_" + os.path.basename(path)[:-3]
|
yield "migration_description_" + os.path.basename(path)[:-3]
|
||||||
|
|
||||||
|
# FIXME: to be removed in bookworm branch
|
||||||
|
yield "migration_description_0027_migrate_to_bookworm"
|
||||||
|
|
||||||
# For each default service, expect to find "service_description_<name>"
|
# For each default service, expect to find "service_description_<name>"
|
||||||
for service, info in yaml.safe_load(
|
for service, info in yaml.safe_load(
|
||||||
open(ROOT + "conf/yunohost/services.yml")
|
open(ROOT + "conf/yunohost/services.yml")
|
||||||
|
|
16
maintenance/shfmt.sh
Executable file
16
maintenance/shfmt.sh
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
shfmt_args=(
|
||||||
|
--indent 4
|
||||||
|
--keep-padding # keep column alignment paddings
|
||||||
|
--space-redirects # redirect operators will be followed by a space
|
||||||
|
--binary-next-line # binary ops like && and | may start a line
|
||||||
|
--case-indent # switch cases will be indented
|
||||||
|
)
|
||||||
|
|
||||||
|
shfmt "${shfmt_args[@]}" "$@" \
|
||||||
|
helpers/helpers \
|
||||||
|
helpers/helpers.v2.1.d/* \
|
||||||
|
helpers/helpers.v2.d/* \
|
||||||
|
hooks/*
|
|
@ -1201,7 +1201,7 @@ backup:
|
||||||
api: PUT /backups/<name>/restore
|
api: PUT /backups/<name>/restore
|
||||||
arguments:
|
arguments:
|
||||||
name:
|
name:
|
||||||
help: Name of the local backup archive
|
help: Name or path of the backup archive
|
||||||
--system:
|
--system:
|
||||||
help: List of system parts to restore (or all if none is given)
|
help: List of system parts to restore (or all if none is given)
|
||||||
nargs: "*"
|
nargs: "*"
|
||||||
|
@ -1232,7 +1232,7 @@ backup:
|
||||||
api: GET /backups/<name>
|
api: GET /backups/<name>
|
||||||
arguments:
|
arguments:
|
||||||
name:
|
name:
|
||||||
help: Name of the local backup archive
|
help: Name or path of the backup archive
|
||||||
-d:
|
-d:
|
||||||
full: --with-details
|
full: --with-details
|
||||||
help: Show additional backup information
|
help: Show additional backup information
|
||||||
|
@ -2079,6 +2079,6 @@ diagnosis:
|
||||||
api: PUT /diagnosis/unignore
|
api: PUT /diagnosis/unignore
|
||||||
arguments:
|
arguments:
|
||||||
--filter:
|
--filter:
|
||||||
help: Remove a filter (it should be an existing filter as listed with --list)
|
help: Remove a filter (it should be an existing filter as listed with "ignore --list")
|
||||||
nargs: "*"
|
nargs: "*"
|
||||||
metavar: CRITERIA
|
metavar: CRITERIA
|
||||||
|
|
|
@ -142,6 +142,17 @@ name = "Email"
|
||||||
visible="smtp_relay_enabled"
|
visible="smtp_relay_enabled"
|
||||||
help = "" # This is empty string on purpose, otherwise the core automatically set the 'good_practice_admin_password' string here which is not relevant, because the admin is not actually "choosing" the password ...
|
help = "" # This is empty string on purpose, otherwise the core automatically set the 'good_practice_admin_password' string here which is not relevant, because the admin is not actually "choosing" the password ...
|
||||||
|
|
||||||
|
[email.smtp.smtp_backup_mx_domains]
|
||||||
|
type = "string"
|
||||||
|
default = ""
|
||||||
|
optional = true
|
||||||
|
|
||||||
|
[email.smtp.smtp_backup_mx_emails_whitelisted]
|
||||||
|
type = "string"
|
||||||
|
default = ""
|
||||||
|
optional = true
|
||||||
|
visible = "smtp_backup_mx_domains"
|
||||||
|
|
||||||
[misc]
|
[misc]
|
||||||
name = "Other"
|
name = "Other"
|
||||||
[misc.portal]
|
[misc.portal]
|
||||||
|
|
|
@ -168,15 +168,6 @@
|
||||||
ipv6: false
|
ipv6: false
|
||||||
domain: false
|
domain: false
|
||||||
non_blacklisted_return_code: []
|
non_blacklisted_return_code: []
|
||||||
# Used by GAFAM
|
|
||||||
- name: SenderScore Blacklist
|
|
||||||
dns_server: bl.score.senderscore.com
|
|
||||||
website: https://senderscore.com
|
|
||||||
ipv4: true
|
|
||||||
ipv6: false
|
|
||||||
domain: false
|
|
||||||
# Added cause it supports IPv6
|
|
||||||
non_blacklisted_return_code: []
|
|
||||||
- name: AntiCaptcha.NET IPv6
|
- name: AntiCaptcha.NET IPv6
|
||||||
dns_server: dnsbl6.anticaptcha.net
|
dns_server: dnsbl6.anticaptcha.net
|
||||||
website: http://anticaptcha.net/
|
website: http://anticaptcha.net/
|
||||||
|
|
217
src/app.py
217
src/app.py
|
@ -328,10 +328,7 @@ def app_map(app=None, raw=False, user=None):
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
if app is not None:
|
if app is not None:
|
||||||
if not _is_installed(app):
|
_assert_is_installed(app)
|
||||||
raise YunohostValidationError(
|
|
||||||
"app_not_installed", app=app, all_apps=_get_all_installed_apps_id()
|
|
||||||
)
|
|
||||||
apps = [
|
apps = [
|
||||||
app,
|
app,
|
||||||
]
|
]
|
||||||
|
@ -770,7 +767,10 @@ def app_upgrade(
|
||||||
from yunohost.utils.resources import AppResourceManager
|
from yunohost.utils.resources import AppResourceManager
|
||||||
|
|
||||||
AppResourceManager(
|
AppResourceManager(
|
||||||
app_instance_name, wanted=manifest, current=app_dict["manifest"]
|
app_instance_name,
|
||||||
|
wanted=manifest,
|
||||||
|
current=app_dict["manifest"],
|
||||||
|
workdir=extracted_app_folder,
|
||||||
).apply(
|
).apply(
|
||||||
rollback_and_raise_exception_if_failure=True,
|
rollback_and_raise_exception_if_failure=True,
|
||||||
operation_logger=operation_logger,
|
operation_logger=operation_logger,
|
||||||
|
@ -846,6 +846,41 @@ def app_upgrade(
|
||||||
+ "\n -".join(manually_modified_files_by_app)
|
+ "\n -".join(manually_modified_files_by_app)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# If the upgrade didnt fail, update the revision and app files (even if it broke the system, otherwise we end up in a funky intermediate state where the app files don't match the installed version or settings, for example for v1->v2 upgrade marked as "broke the system" for some reason)
|
||||||
|
if not upgrade_failed:
|
||||||
|
now = int(time.time())
|
||||||
|
app_setting(app_instance_name, "update_time", now)
|
||||||
|
app_setting(
|
||||||
|
app_instance_name,
|
||||||
|
"current_revision",
|
||||||
|
manifest.get("remote", {}).get("revision", "?"),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Clean hooks and add new ones
|
||||||
|
hook_remove(app_instance_name)
|
||||||
|
if "hooks" in os.listdir(extracted_app_folder):
|
||||||
|
for hook in os.listdir(extracted_app_folder + "/hooks"):
|
||||||
|
hook_add(
|
||||||
|
app_instance_name, extracted_app_folder + "/hooks/" + hook
|
||||||
|
)
|
||||||
|
|
||||||
|
# Replace scripts and manifest and conf (if exists)
|
||||||
|
# Move scripts and manifest to the right place
|
||||||
|
for file_to_copy in APP_FILES_TO_COPY:
|
||||||
|
rm(f"{app_setting_path}/{file_to_copy}", recursive=True, force=True)
|
||||||
|
if os.path.exists(os.path.join(extracted_app_folder, file_to_copy)):
|
||||||
|
cp(
|
||||||
|
f"{extracted_app_folder}/{file_to_copy}",
|
||||||
|
f"{app_setting_path}/{file_to_copy}",
|
||||||
|
recursive=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Clean and set permissions
|
||||||
|
shutil.rmtree(extracted_app_folder)
|
||||||
|
chmod(app_setting_path, 0o600)
|
||||||
|
chmod(f"{app_setting_path}/settings.yml", 0o400)
|
||||||
|
chown(app_setting_path, "root", recursive=True)
|
||||||
|
|
||||||
# If upgrade failed or broke the system,
|
# If upgrade failed or broke the system,
|
||||||
# raise an error and interrupt all other pending upgrades
|
# raise an error and interrupt all other pending upgrades
|
||||||
if upgrade_failed or broke_the_system:
|
if upgrade_failed or broke_the_system:
|
||||||
|
@ -896,36 +931,6 @@ def app_upgrade(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Otherwise we're good and keep going !
|
# Otherwise we're good and keep going !
|
||||||
now = int(time.time())
|
|
||||||
app_setting(app_instance_name, "update_time", now)
|
|
||||||
app_setting(
|
|
||||||
app_instance_name,
|
|
||||||
"current_revision",
|
|
||||||
manifest.get("remote", {}).get("revision", "?"),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Clean hooks and add new ones
|
|
||||||
hook_remove(app_instance_name)
|
|
||||||
if "hooks" in os.listdir(extracted_app_folder):
|
|
||||||
for hook in os.listdir(extracted_app_folder + "/hooks"):
|
|
||||||
hook_add(app_instance_name, extracted_app_folder + "/hooks/" + hook)
|
|
||||||
|
|
||||||
# Replace scripts and manifest and conf (if exists)
|
|
||||||
# Move scripts and manifest to the right place
|
|
||||||
for file_to_copy in APP_FILES_TO_COPY:
|
|
||||||
rm(f"{app_setting_path}/{file_to_copy}", recursive=True, force=True)
|
|
||||||
if os.path.exists(os.path.join(extracted_app_folder, file_to_copy)):
|
|
||||||
cp(
|
|
||||||
f"{extracted_app_folder}/{file_to_copy}",
|
|
||||||
f"{app_setting_path}/{file_to_copy}",
|
|
||||||
recursive=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Clean and set permissions
|
|
||||||
shutil.rmtree(extracted_app_folder)
|
|
||||||
chmod(app_setting_path, 0o600)
|
|
||||||
chmod(f"{app_setting_path}/settings.yml", 0o400)
|
|
||||||
chown(app_setting_path, "root", recursive=True)
|
|
||||||
|
|
||||||
# So much win
|
# So much win
|
||||||
logger.success(m18n.n("app_upgraded", app=app_instance_name))
|
logger.success(m18n.n("app_upgraded", app=app_instance_name))
|
||||||
|
@ -1416,10 +1421,7 @@ def app_remove(operation_logger, app, purge=False, force_workdir=None):
|
||||||
)
|
)
|
||||||
from yunohost.domain import domain_list, domain_config_get, domain_config_set
|
from yunohost.domain import domain_list, domain_config_get, domain_config_set
|
||||||
|
|
||||||
if not _is_installed(app):
|
_assert_is_installed(app)
|
||||||
raise YunohostValidationError(
|
|
||||||
"app_not_installed", app=app, all_apps=_get_all_installed_apps_id()
|
|
||||||
)
|
|
||||||
|
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
|
@ -1996,6 +1998,7 @@ ynh_app_config_run $1
|
||||||
"install_dir": settings.get("install_dir", ""),
|
"install_dir": settings.get("install_dir", ""),
|
||||||
"YNH_APP_BASEDIR": os.path.join(APPS_SETTING_PATH, app),
|
"YNH_APP_BASEDIR": os.path.join(APPS_SETTING_PATH, app),
|
||||||
"YNH_APP_PACKAGING_FORMAT": str(manifest["packaging_format"]),
|
"YNH_APP_PACKAGING_FORMAT": str(manifest["packaging_format"]),
|
||||||
|
"YNH_APP_CONFIG_PANEL_OPTIONS_TYPES_AND_BINDS": self._dump_options_types_and_binds(),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
app_script_env = _make_environment_for_app_script(app)
|
app_script_env = _make_environment_for_app_script(app)
|
||||||
|
@ -2014,8 +2017,68 @@ ynh_app_config_run $1
|
||||||
raise YunohostError("app_action_failed", action=action, app=app)
|
raise YunohostError("app_action_failed", action=action, app=app)
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
def _get_config_panel(self):
|
||||||
|
|
||||||
def _get_app_settings(app):
|
ret = super()._get_config_panel()
|
||||||
|
|
||||||
|
self._compute_binds()
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def _compute_binds(self):
|
||||||
|
"""
|
||||||
|
This compute the 'bind' statement for every option
|
||||||
|
In particular to handle __FOOBAR__ syntax
|
||||||
|
and to handle the fact that bind statements may be defined panel-wide or section-wide
|
||||||
|
"""
|
||||||
|
|
||||||
|
settings = _get_app_settings(self.entity)
|
||||||
|
|
||||||
|
for panel, section, option in self._iterate():
|
||||||
|
|
||||||
|
bind_panel = panel.get("bind")
|
||||||
|
|
||||||
|
bind_section = section.get("bind")
|
||||||
|
if not bind_section:
|
||||||
|
bind_section = bind_panel
|
||||||
|
elif bind_section[-1] == ":" and bind_panel and ":" in bind_panel:
|
||||||
|
selector, bind_panel_file = bind_panel.split(":")
|
||||||
|
if ">" in bind_section:
|
||||||
|
bind_section = bind_section + bind_panel_file
|
||||||
|
else:
|
||||||
|
bind_section = selector + bind_section + bind_panel_file
|
||||||
|
|
||||||
|
bind = option.get("bind")
|
||||||
|
if not bind:
|
||||||
|
if bind_section:
|
||||||
|
bind = bind_section
|
||||||
|
else:
|
||||||
|
bind = "settings"
|
||||||
|
elif bind[-1] == ":" and bind_section and ":" in bind_section:
|
||||||
|
selector, bind_file = bind_section.split(":")
|
||||||
|
if ">" in bind:
|
||||||
|
bind = bind + bind_file
|
||||||
|
else:
|
||||||
|
bind = selector + bind + bind_file
|
||||||
|
if bind == "settings" and option.get("type", "string") == "file":
|
||||||
|
bind = "null"
|
||||||
|
|
||||||
|
option["bind"] = _hydrate_app_template(bind, settings)
|
||||||
|
|
||||||
|
def _dump_options_types_and_binds(self):
|
||||||
|
lines = []
|
||||||
|
for _, _, option in self._iterate():
|
||||||
|
lines.append(
|
||||||
|
"|".join([option["id"], option.get("type", "string"), option["bind"]])
|
||||||
|
)
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
app_settings_cache: Dict[str, Dict[str, Any]] = {}
|
||||||
|
app_settings_cache_timestamp: Dict[str, float] = {}
|
||||||
|
|
||||||
|
|
||||||
|
def _get_app_settings(app: str) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Get settings of an installed app
|
Get settings of an installed app
|
||||||
|
|
||||||
|
@ -2023,12 +2086,22 @@ def _get_app_settings(app):
|
||||||
app -- The app id (like nextcloud__2)
|
app -- The app id (like nextcloud__2)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not _is_installed(app):
|
_assert_is_installed(app)
|
||||||
raise YunohostValidationError(
|
|
||||||
"app_not_installed", app=app, all_apps=_get_all_installed_apps_id()
|
global app_settings_cache
|
||||||
)
|
global app_settings_cache_timestamp
|
||||||
|
|
||||||
|
app_setting_path = os.path.join(APPS_SETTING_PATH, app, "settings.yml")
|
||||||
|
app_setting_timestamp = os.path.getmtime(app_setting_path)
|
||||||
|
|
||||||
|
# perf: app settings are cached using the settings.yml's modification date,
|
||||||
|
# such that we don't have to worry too much about calling this function
|
||||||
|
# too many times (because ultimately parsing yml is not free)
|
||||||
|
if app_settings_cache_timestamp.get(app) == app_setting_timestamp:
|
||||||
|
return app_settings_cache[app].copy()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(APPS_SETTING_PATH, app, "settings.yml")) as f:
|
with open(app_setting_path) as f:
|
||||||
settings = yaml.safe_load(f) or {}
|
settings = yaml.safe_load(f) or {}
|
||||||
# If label contains unicode char, this may later trigger issues when building strings...
|
# If label contains unicode char, this may later trigger issues when building strings...
|
||||||
# FIXME: this should be propagated to read_yaml so that this fix applies everywhere I think...
|
# FIXME: this should be propagated to read_yaml so that this fix applies everywhere I think...
|
||||||
|
@ -2060,7 +2133,14 @@ def _get_app_settings(app):
|
||||||
# Make the app id available as $app too
|
# Make the app id available as $app too
|
||||||
settings["app"] = app
|
settings["app"] = app
|
||||||
|
|
||||||
if app == settings["id"]:
|
# FIXME: it's not clear why this code exists... Shouldn't we hard-define 'id' as $app ...?
|
||||||
|
if app != settings["id"]:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
# Cache the settings
|
||||||
|
app_settings_cache[app] = settings.copy()
|
||||||
|
app_settings_cache_timestamp[app] = app_setting_timestamp
|
||||||
|
|
||||||
return settings
|
return settings
|
||||||
except (IOError, TypeError, KeyError):
|
except (IOError, TypeError, KeyError):
|
||||||
logger.error(m18n.n("app_not_correctly_installed", app=app))
|
logger.error(m18n.n("app_not_correctly_installed", app=app))
|
||||||
|
@ -2079,6 +2159,11 @@ def _set_app_settings(app, settings):
|
||||||
with open(os.path.join(APPS_SETTING_PATH, app, "settings.yml"), "w") as f:
|
with open(os.path.join(APPS_SETTING_PATH, app, "settings.yml"), "w") as f:
|
||||||
yaml.safe_dump(settings, f, default_flow_style=False)
|
yaml.safe_dump(settings, f, default_flow_style=False)
|
||||||
|
|
||||||
|
if app in app_settings_cache_timestamp:
|
||||||
|
del app_settings_cache_timestamp[app]
|
||||||
|
if app in app_settings_cache:
|
||||||
|
del app_settings_cache[app]
|
||||||
|
|
||||||
|
|
||||||
def _get_manifest_of_app(path):
|
def _get_manifest_of_app(path):
|
||||||
"Get app manifest stored in json or in toml"
|
"Get app manifest stored in json or in toml"
|
||||||
|
@ -2686,16 +2771,6 @@ def _list_upgradable_apps():
|
||||||
|
|
||||||
|
|
||||||
def _is_installed(app: str) -> bool:
|
def _is_installed(app: str) -> bool:
|
||||||
"""
|
|
||||||
Check if application is installed
|
|
||||||
|
|
||||||
Keyword arguments:
|
|
||||||
app -- id of App to check
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Boolean
|
|
||||||
|
|
||||||
"""
|
|
||||||
return os.path.isdir(APPS_SETTING_PATH + app)
|
return os.path.isdir(APPS_SETTING_PATH + app)
|
||||||
|
|
||||||
|
|
||||||
|
@ -2929,7 +3004,9 @@ def _get_conflicting_apps(domain, path, ignore_app=None):
|
||||||
for p, a in apps_map[domain].items():
|
for p, a in apps_map[domain].items():
|
||||||
if a["id"] == ignore_app:
|
if a["id"] == ignore_app:
|
||||||
continue
|
continue
|
||||||
if path == p or path == "/" or p == "/":
|
if path == p or (
|
||||||
|
not path.startswith("/.well-known/") and (path == "/" or p == "/")
|
||||||
|
):
|
||||||
conflicts.append((p, a["id"], a["label"]))
|
conflicts.append((p, a["id"], a["label"]))
|
||||||
|
|
||||||
return conflicts
|
return conflicts
|
||||||
|
@ -2992,19 +3069,43 @@ def _make_environment_for_app_script(
|
||||||
# If packaging format v2, load all settings
|
# If packaging format v2, load all settings
|
||||||
if manifest["packaging_format"] >= 2 or force_include_app_settings:
|
if manifest["packaging_format"] >= 2 or force_include_app_settings:
|
||||||
env_dict["app"] = app
|
env_dict["app"] = app
|
||||||
|
data_to_redact = []
|
||||||
|
prefixes_or_suffixes_to_redact = [
|
||||||
|
"pwd",
|
||||||
|
"pass",
|
||||||
|
"passwd",
|
||||||
|
"password",
|
||||||
|
"passphrase",
|
||||||
|
"secret",
|
||||||
|
"key",
|
||||||
|
"token",
|
||||||
|
]
|
||||||
|
|
||||||
for setting_name, setting_value in _get_app_settings(app).items():
|
for setting_name, setting_value in _get_app_settings(app).items():
|
||||||
# Ignore special internal settings like checksum__
|
# Ignore special internal settings like checksum__
|
||||||
# (not a huge deal to load them but idk...)
|
# (not a huge deal to load them but idk...)
|
||||||
if setting_name.startswith("checksum__"):
|
if setting_name.startswith("checksum__"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
env_dict[setting_name] = str(setting_value)
|
setting_value = str(setting_value)
|
||||||
|
env_dict[setting_name] = setting_value
|
||||||
|
|
||||||
|
# Check if we should redact this setting value
|
||||||
|
# (the check on the setting length exists to prevent stupid stuff like redacting empty string or something which is actually just 0/1, true/false, ...
|
||||||
|
if len(setting_value) > 6 and any(
|
||||||
|
setting_name.startswith(p) or setting_name.endswith(p)
|
||||||
|
for p in prefixes_or_suffixes_to_redact
|
||||||
|
):
|
||||||
|
data_to_redact.append(setting_value)
|
||||||
|
|
||||||
# Special weird case for backward compatibility...
|
# Special weird case for backward compatibility...
|
||||||
# 'path' was loaded into 'path_url' .....
|
# 'path' was loaded into 'path_url' .....
|
||||||
if "path" in env_dict:
|
if "path" in env_dict:
|
||||||
env_dict["path_url"] = env_dict["path"]
|
env_dict["path_url"] = env_dict["path"]
|
||||||
|
|
||||||
|
for operation_logger in OperationLogger._instances:
|
||||||
|
operation_logger.data_to_redact.extend(data_to_redact)
|
||||||
|
|
||||||
return env_dict
|
return env_dict
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1923,6 +1923,9 @@ class TarBackupMethod(BackupMethod):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _archive_file(self):
|
def _archive_file(self):
|
||||||
|
if isinstance(self.manager, RestoreManager):
|
||||||
|
return self.manager.archive_path
|
||||||
|
|
||||||
if isinstance(self.manager, BackupManager) and settings_get(
|
if isinstance(self.manager, BackupManager) and settings_get(
|
||||||
"misc.backup.backup_compress_tar_archives"
|
"misc.backup.backup_compress_tar_archives"
|
||||||
):
|
):
|
||||||
|
@ -2314,11 +2317,6 @@ def backup_restore(name, system=[], apps=[], force=False):
|
||||||
# Initialize #
|
# Initialize #
|
||||||
#
|
#
|
||||||
|
|
||||||
if name.endswith(".tar.gz"):
|
|
||||||
name = name[: -len(".tar.gz")]
|
|
||||||
elif name.endswith(".tar"):
|
|
||||||
name = name[: -len(".tar")]
|
|
||||||
|
|
||||||
restore_manager = RestoreManager(name)
|
restore_manager = RestoreManager(name)
|
||||||
|
|
||||||
restore_manager.set_system_targets(system)
|
restore_manager.set_system_targets(system)
|
||||||
|
@ -2330,8 +2328,10 @@ def backup_restore(name, system=[], apps=[], force=False):
|
||||||
# Add validation if restoring system parts on an already-installed system
|
# Add validation if restoring system parts on an already-installed system
|
||||||
#
|
#
|
||||||
|
|
||||||
if restore_manager.targets.targets["system"] != [] and os.path.isfile(
|
if (
|
||||||
"/etc/yunohost/installed"
|
restore_manager.info["system"] != {}
|
||||||
|
and restore_manager.targets.targets["system"] != []
|
||||||
|
and os.path.isfile("/etc/yunohost/installed")
|
||||||
):
|
):
|
||||||
logger.warning(m18n.n("yunohost_already_installed"))
|
logger.warning(m18n.n("yunohost_already_installed"))
|
||||||
if not force:
|
if not force:
|
||||||
|
@ -2451,6 +2451,7 @@ def backup_info(name, with_details=False, human_readable=False):
|
||||||
human_readable -- Print sizes in human readable format
|
human_readable -- Print sizes in human readable format
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
original_name = name
|
||||||
|
|
||||||
if name.endswith(".tar.gz"):
|
if name.endswith(".tar.gz"):
|
||||||
name = name[: -len(".tar.gz")]
|
name = name[: -len(".tar.gz")]
|
||||||
|
@ -2462,6 +2463,9 @@ def backup_info(name, with_details=False, human_readable=False):
|
||||||
# Check file exist (even if it's a broken symlink)
|
# Check file exist (even if it's a broken symlink)
|
||||||
if not os.path.lexists(archive_file):
|
if not os.path.lexists(archive_file):
|
||||||
archive_file += ".gz"
|
archive_file += ".gz"
|
||||||
|
if not os.path.lexists(archive_file):
|
||||||
|
# Maybe the user provided a path to the backup?
|
||||||
|
archive_file = original_name
|
||||||
if not os.path.lexists(archive_file):
|
if not os.path.lexists(archive_file):
|
||||||
raise YunohostValidationError("backup_archive_name_unknown", name=name)
|
raise YunohostValidationError("backup_archive_name_unknown", name=name)
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,16 @@ class MyDiagnoser(Diagnoser):
|
||||||
summary="diagnosis_high_number_auth_failures",
|
summary="diagnosis_high_number_auth_failures",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
rfkill_wifi = self.rfkill_wifi()
|
||||||
|
if len(rfkill_wifi) > 0:
|
||||||
|
yield dict(
|
||||||
|
meta={"test": "rfkill_wifi"},
|
||||||
|
status="ERROR",
|
||||||
|
summary="diagnosis_rfkill_wifi",
|
||||||
|
details=["diagnosis_rfkill_wifi_details"],
|
||||||
|
data={"rfkill_wifi_error": rfkill_wifi},
|
||||||
|
)
|
||||||
|
|
||||||
def bad_sury_packages(self):
|
def bad_sury_packages(self):
|
||||||
packages_to_check = ["openssl", "libssl1.1", "libssl-dev"]
|
packages_to_check = ["openssl", "libssl1.1", "libssl-dev"]
|
||||||
for package in packages_to_check:
|
for package in packages_to_check:
|
||||||
|
@ -301,3 +311,10 @@ class MyDiagnoser(Diagnoser):
|
||||||
)
|
)
|
||||||
write_to_json(cache_file, CVEs)
|
write_to_json(cache_file, CVEs)
|
||||||
return CVEs[0]["VULNERABLE"]
|
return CVEs[0]["VULNERABLE"]
|
||||||
|
|
||||||
|
def rfkill_wifi(self):
|
||||||
|
if os.path.isfile("/etc/profile.d/wifi-check.sh"):
|
||||||
|
cmd = "bash /etc/profile.d/wifi-check.sh"
|
||||||
|
return check_output(cmd)
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
|
@ -217,7 +217,9 @@ class MyDiagnoser(Diagnoser):
|
||||||
}
|
}
|
||||||
if "v=DMARC1" in r["value"]:
|
if "v=DMARC1" in r["value"]:
|
||||||
for param in current:
|
for param in current:
|
||||||
key, value = param.split("=")
|
if "=" not in param:
|
||||||
|
return False
|
||||||
|
key, value = param.split("=", 1)
|
||||||
if key == "p":
|
if key == "p":
|
||||||
return value in ["none", "quarantine", "reject"]
|
return value in ["none", "quarantine", "reject"]
|
||||||
return expected == current
|
return expected == current
|
||||||
|
|
|
@ -263,16 +263,12 @@ def _diagnosis_ignore(add_filter=None, remove_filter=None, list=False):
|
||||||
|
|
||||||
# Sanity checks for the provided arguments
|
# Sanity checks for the provided arguments
|
||||||
if len(filter_) == 0:
|
if len(filter_) == 0:
|
||||||
raise YunohostValidationError(
|
raise YunohostValidationError(m18n.n("diagnosis_ignore_missing_criteria"))
|
||||||
"You should provide at least one criteria being the diagnosis category to ignore"
|
|
||||||
)
|
|
||||||
category = filter_[0]
|
category = filter_[0]
|
||||||
if category not in all_categories_names:
|
if category not in all_categories_names:
|
||||||
raise YunohostValidationError(f"{category} is not a diagnosis category")
|
raise YunohostValidationError(f"{category} is not a diagnosis category")
|
||||||
if any("=" not in criteria for criteria in filter_[1:]):
|
if any("=" not in criteria for criteria in filter_[1:]):
|
||||||
raise YunohostValidationError(
|
raise YunohostValidationError(m18n.n("diagnosis_ignore_criteria_error"))
|
||||||
"Criterias should be of the form key=value (e.g. domain=yolo.test)"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Convert the provided criteria into a nice dict
|
# Convert the provided criteria into a nice dict
|
||||||
criterias = {c.split("=")[0]: c.split("=")[1] for c in filter_[1:]}
|
criterias = {c.split("=")[0]: c.split("=")[1] for c in filter_[1:]}
|
||||||
|
@ -295,7 +291,7 @@ def _diagnosis_ignore(add_filter=None, remove_filter=None, list=False):
|
||||||
issue_matches_criterias(i, criterias)
|
issue_matches_criterias(i, criterias)
|
||||||
for i in current_issues_for_this_category
|
for i in current_issues_for_this_category
|
||||||
):
|
):
|
||||||
raise YunohostError("No issues was found matching the given criteria.")
|
raise YunohostError(m18n.n("diagnosis_ignore_no_issue_found"))
|
||||||
|
|
||||||
# Make sure the subdicts/lists exists
|
# Make sure the subdicts/lists exists
|
||||||
if "ignore_filters" not in configuration:
|
if "ignore_filters" not in configuration:
|
||||||
|
@ -304,12 +300,14 @@ def _diagnosis_ignore(add_filter=None, remove_filter=None, list=False):
|
||||||
configuration["ignore_filters"][category] = []
|
configuration["ignore_filters"][category] = []
|
||||||
|
|
||||||
if criterias in configuration["ignore_filters"][category]:
|
if criterias in configuration["ignore_filters"][category]:
|
||||||
logger.warning("This filter already exists.")
|
logger.warning(
|
||||||
|
m18n.n("diagnosis_ignore_already_filtered", category=category)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
configuration["ignore_filters"][category].append(criterias)
|
configuration["ignore_filters"][category].append(criterias)
|
||||||
_diagnosis_write_configuration(configuration)
|
_diagnosis_write_configuration(configuration)
|
||||||
logger.success("Filter added")
|
logger.success(m18n.n("diagnosis_ignore_filter_added", category=category))
|
||||||
return
|
return
|
||||||
|
|
||||||
if remove_filter:
|
if remove_filter:
|
||||||
|
@ -322,11 +320,14 @@ def _diagnosis_ignore(add_filter=None, remove_filter=None, list=False):
|
||||||
configuration["ignore_filters"][category] = []
|
configuration["ignore_filters"][category] = []
|
||||||
|
|
||||||
if criterias not in configuration["ignore_filters"][category]:
|
if criterias not in configuration["ignore_filters"][category]:
|
||||||
raise YunohostValidationError("This filter does not exists.")
|
logger.warning(
|
||||||
|
m18n.n("diagnosis_ignore_no_filter_found", category=category)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
configuration["ignore_filters"][category].remove(criterias)
|
configuration["ignore_filters"][category].remove(criterias)
|
||||||
_diagnosis_write_configuration(configuration)
|
_diagnosis_write_configuration(configuration)
|
||||||
logger.success("Filter removed")
|
logger.success(m18n.n("diagnosis_ignore_filter_removed", category=category))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -481,6 +481,15 @@ def _get_dns_zone_for_domain(domain):
|
||||||
else:
|
else:
|
||||||
zone = parent_list[-1]
|
zone = parent_list[-1]
|
||||||
|
|
||||||
|
# Adding this otherwise the CI is flooding about those ...
|
||||||
|
if domain not in [
|
||||||
|
"example.tld",
|
||||||
|
"sub.example.tld",
|
||||||
|
"domain.tld",
|
||||||
|
"sub.domain.tld",
|
||||||
|
"domain_a.dev",
|
||||||
|
"domain_b.dev",
|
||||||
|
]:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Could not identify correctly the dns zone for domain {domain}, returning {zone}"
|
f"Could not identify correctly the dns zone for domain {domain}, returning {zone}"
|
||||||
)
|
)
|
||||||
|
|
|
@ -538,6 +538,9 @@ def hook_exec_with_script_debug_if_failure(*args, **kwargs):
|
||||||
failed = True if retcode != 0 else False
|
failed = True if retcode != 0 else False
|
||||||
if failed:
|
if failed:
|
||||||
error = error_message_if_script_failed
|
error = error_message_if_script_failed
|
||||||
|
# check more specific error message added by ynh_die in $YNH_STDRETURN
|
||||||
|
if isinstance(retpayload, dict) and "error" in retpayload:
|
||||||
|
error += " : " + retpayload["error"].strip()
|
||||||
logger.error(error_message_if_failed(error))
|
logger.error(error_message_if_failed(error))
|
||||||
failure_message_with_debug_instructions = operation_logger.error(error)
|
failure_message_with_debug_instructions = operation_logger.error(error)
|
||||||
if Moulinette.interface.type != "api":
|
if Moulinette.interface.type != "api":
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue