mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge remote-tracking branch 'origin/dev' into bookworm
This commit is contained in:
commit
bdc296f858
12 changed files with 71 additions and 29 deletions
|
@ -1,3 +1,3 @@
|
|||
location / {
|
||||
return 302 https://$http_host/yunohost/admin;
|
||||
return 302 https://$host/yunohost/admin;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ server {
|
|||
{# Note that this != "False" is meant to be failure-safe, in the case the redrect_to_https would happen to contain empty string or whatever value. We absolutely don't want to disable the HTTPS redirect *except* when it's explicitly being asked to be disabled. #}
|
||||
{% if redirect_to_https != "False" %}
|
||||
location / {
|
||||
return 301 https://$http_host$request_uri;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
{# The app config snippets are not included in the HTTP conf unless HTTPS redirect is disabled, because app's location may blocks will conflict or bypass/ignore the HTTPS redirection. #}
|
||||
{% else %}
|
||||
|
|
|
@ -4,7 +4,7 @@ location /yunohost/api/ {
|
|||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
{% if webadmin_allowlist_enabled == "True" %}
|
||||
{% for ip in webadmin_allowlist.split(',') %}
|
||||
|
|
7
debian/changelog
vendored
7
debian/changelog
vendored
|
@ -4,6 +4,13 @@ yunohost (12.0.0) unstable; urgency=low
|
|||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 04 May 2023 20:30:19 +0200
|
||||
|
||||
yunohost (11.1.21.4) stable; urgency=low
|
||||
|
||||
- regenconf: Get rid of previous tmp hack about /dev/null for people that went through the very first 11.1.21, because it's causing issue in unpriviledged LXC or similar context (8242cab7)
|
||||
- apps: don't attempt to del password key if it doesn't exist (29338f79)
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Wed, 14 Jun 2023 15:48:33 +0200
|
||||
|
||||
yunohost (11.1.21.3) stable; urgency=low
|
||||
|
||||
- Fix again /var/www/.well-known/ynh-diagnosis/ perms which are too broad and could be exploited to serve malicious files x_x (84984ad8)
|
||||
|
|
|
@ -124,7 +124,7 @@ ynh_remove_apps() {
|
|||
# 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.
|
||||
# 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() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=a
|
||||
|
@ -176,9 +176,10 @@ ynh_spawn_app_shell() {
|
|||
# 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} \"\$@\"; }"
|
||||
eval "php() { php${phpversion} ${phpflags} \"\$@\"; }"
|
||||
export -f php
|
||||
fi
|
||||
|
||||
|
|
|
@ -872,6 +872,8 @@ app:
|
|||
### app_shell()
|
||||
shell:
|
||||
action_help: Open an interactive shell with the app environment already loaded
|
||||
# Here we set a GET only not to lock the command line. There is no actual API endpoint for app_shell()
|
||||
api: GET /apps/<app>/shell
|
||||
arguments:
|
||||
app:
|
||||
help: App ID
|
||||
|
|
|
@ -84,7 +84,7 @@ re_app_instance_name = re.compile(
|
|||
)
|
||||
|
||||
APP_REPO_URL = re.compile(
|
||||
r"^https://[a-zA-Z0-9-_.]+/[a-zA-Z0-9-_./~]+/[a-zA-Z0-9-_.]+_ynh(/?(-/)?tree/[a-zA-Z0-9-_.]+)?(\.git)?/?$"
|
||||
r"^https://[a-zA-Z0-9-_.]+/[a-zA-Z0-9-_./~]+/[a-zA-Z0-9-_.]+_ynh(/?(-/)?(tree|src/(branch|tag|commit))/[a-zA-Z0-9-_.]+)?(\.git)?/?$"
|
||||
)
|
||||
|
||||
APP_FILES_TO_COPY = [
|
||||
|
@ -1193,7 +1193,8 @@ def app_install(
|
|||
for question in questions:
|
||||
# Or should it be more generally question.redact ?
|
||||
if question.type == "password":
|
||||
del env_dict_for_logging[f"YNH_APP_ARG_{question.name.upper()}"]
|
||||
if f"YNH_APP_ARG_{question.name.upper()}" in env_dict_for_logging:
|
||||
del env_dict_for_logging[f"YNH_APP_ARG_{question.name.upper()}"]
|
||||
if question.name in env_dict_for_logging:
|
||||
del env_dict_for_logging[question.name]
|
||||
|
||||
|
|
|
@ -182,6 +182,10 @@ class MyDiagnoser(Diagnoser):
|
|||
if success != "ok":
|
||||
return None
|
||||
else:
|
||||
if type_ == "TXT" and isinstance(answers,list):
|
||||
for part in answers:
|
||||
if part.startswith('"v=spf1'):
|
||||
return part
|
||||
return answers[0] if len(answers) == 1 else answers
|
||||
|
||||
def current_record_match_expected(self, r):
|
||||
|
|
|
@ -331,7 +331,7 @@ def firewall_reload(skip_upnp=False):
|
|||
# Refresh port forwarding with UPnP
|
||||
firewall_upnp(no_refresh=False)
|
||||
|
||||
_run_service_command("reload", "fail2ban")
|
||||
_run_service_command("restart", "fail2ban")
|
||||
|
||||
if errors:
|
||||
logger.warning(m18n.n("firewall_rules_cmd_failed"))
|
||||
|
|
|
@ -69,8 +69,19 @@ def test_repo_url_definition():
|
|||
assert _is_app_repo_url("git@github.com:YunoHost-Apps/foobar_ynh.git")
|
||||
assert _is_app_repo_url("https://git.super.host/~max/foobar_ynh")
|
||||
|
||||
### Gitea
|
||||
assert _is_app_repo_url("https://gitea.instance.tld/user/repo_ynh")
|
||||
assert _is_app_repo_url("https://gitea.instance.tld/user/repo_ynh/src/branch/branch_name")
|
||||
assert _is_app_repo_url("https://gitea.instance.tld/user/repo_ynh/src/tag/tag_name")
|
||||
assert _is_app_repo_url("https://gitea.instance.tld/user/repo_ynh/src/commit/abcd1234")
|
||||
|
||||
### Invalid patterns
|
||||
|
||||
# no schema
|
||||
assert not _is_app_repo_url("github.com/YunoHost-Apps/foobar_ynh")
|
||||
# http
|
||||
assert not _is_app_repo_url("http://github.com/YunoHost-Apps/foobar_ynh")
|
||||
# does not end in `_ynh`
|
||||
assert not _is_app_repo_url("https://github.com/YunoHost-Apps/foobar_wat")
|
||||
assert not _is_app_repo_url("https://github.com/YunoHost-Apps/foobar_ynh_wat")
|
||||
assert not _is_app_repo_url("https://github.com/YunoHost-Apps/foobar/tree/testing")
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import pwd
|
||||
import re
|
||||
import os
|
||||
import subprocess
|
||||
|
@ -174,6 +175,12 @@ def tools_postinstall(
|
|||
raw_msg=True,
|
||||
)
|
||||
|
||||
# Crash early if the username is already a system user, which is
|
||||
# a common confusion. We don't want to crash later and end up in an half-configured state.
|
||||
all_existing_usernames = {x.pw_name for x in pwd.getpwall()}
|
||||
if username in all_existing_usernames:
|
||||
raise YunohostValidationError("system_username_exists")
|
||||
|
||||
if username in ADMIN_ALIASES:
|
||||
raise YunohostValidationError(
|
||||
f"Unfortunately, {username} cannot be used as a username", raw_msg=True
|
||||
|
|
|
@ -22,7 +22,7 @@ import shutil
|
|||
import random
|
||||
import tempfile
|
||||
import subprocess
|
||||
from typing import Dict, Any, List
|
||||
from typing import Dict, Any, List, Union
|
||||
|
||||
from moulinette import m18n
|
||||
from moulinette.utils.process import check_output
|
||||
|
@ -1011,16 +1011,16 @@ class AptDependenciesAppResource(AppResource):
|
|||
##### Example
|
||||
```toml
|
||||
[resources.apt]
|
||||
packages = "nyancat, lolcat, sl"
|
||||
packages = ["nyancat", "lolcat", "sl"]
|
||||
|
||||
# (this part is optional and corresponds to the legacy ynh_install_extra_app_dependencies helper)
|
||||
extras.yarn.repo = "deb https://dl.yarnpkg.com/debian/ stable main"
|
||||
extras.yarn.key = "https://dl.yarnpkg.com/debian/pubkey.gpg"
|
||||
extras.yarn.packages = "yarn"
|
||||
extras.yarn.packages = ["yarn"]
|
||||
```
|
||||
|
||||
##### Properties
|
||||
- `packages`: Comma-separated list of packages to be installed via `apt`
|
||||
- `packages`: List of packages to be installed via `apt`
|
||||
- `packages_from_raw_bash`: A multi-line bash snippet (using triple quotes as open/close) which should echo additional packages to be installed. Meant to be used for packages to be conditionally installed depending on architecture, debian version, install questions, or other logic.
|
||||
- `extras`: A dict of (repo, key, packages) corresponding to "extra" repositories to fetch dependencies from
|
||||
|
||||
|
@ -1044,20 +1044,14 @@ class AptDependenciesAppResource(AppResource):
|
|||
|
||||
packages: List = []
|
||||
packages_from_raw_bash: str = ""
|
||||
extras: Dict[str, Dict[str, str]] = {}
|
||||
extras: Dict[str, Dict[str, Union[str, List]]] = {}
|
||||
|
||||
def __init__(self, properties: Dict[str, Any], *args, **kwargs):
|
||||
for key, values in properties.get("extras", {}).items():
|
||||
if not all(
|
||||
isinstance(values.get(k), str) for k in ["repo", "key", "packages"]
|
||||
):
|
||||
raise YunohostError(
|
||||
"In apt resource in the manifest: 'extras' repo should have the keys 'repo', 'key' and 'packages' defined and be strings",
|
||||
raw_msg=True,
|
||||
)
|
||||
|
||||
super().__init__(properties, *args, **kwargs)
|
||||
|
||||
if isinstance(self.packages, str):
|
||||
self.packages = [value.strip() for value in self.packages.split(",")]
|
||||
|
||||
if self.packages_from_raw_bash:
|
||||
out, err = self.check_output_bash_snippet(self.packages_from_raw_bash)
|
||||
if err:
|
||||
|
@ -1065,17 +1059,32 @@ class AptDependenciesAppResource(AppResource):
|
|||
"Error while running apt resource packages_from_raw_bash snippet:"
|
||||
)
|
||||
logger.error(err)
|
||||
self.packages += ", " + out.replace("\n", ", ")
|
||||
self.packages += out.split("\n")
|
||||
|
||||
for key, values in self.extras.items():
|
||||
if isinstance(values.get("packages"), str):
|
||||
values["packages"] = [value.strip() for value in values["packages"].split(",")] # type: ignore
|
||||
|
||||
if not isinstance(values.get("repo"), str) \
|
||||
or not isinstance(values.get("key"), str) \
|
||||
or not isinstance(values.get("packages"), list):
|
||||
raise YunohostError(
|
||||
"In apt resource in the manifest: 'extras' repo should have the keys 'repo', 'key' defined as strings and 'packages' defined as list",
|
||||
raw_msg=True,
|
||||
)
|
||||
|
||||
def provision_or_update(self, context: Dict = {}):
|
||||
script = [f"ynh_install_app_dependencies {self.packages}"]
|
||||
script = " ".join(["ynh_install_app_dependencies", *self.packages])
|
||||
for repo, values in self.extras.items():
|
||||
script += [
|
||||
f"ynh_install_extra_app_dependencies --repo='{values['repo']}' --key='{values['key']}' --package='{values['packages']}'"
|
||||
]
|
||||
script += "\n" + " ".join([
|
||||
"ynh_install_extra_app_dependencies",
|
||||
f"--repo='{values['repo']}'",
|
||||
f"--key='{values['key']}'",
|
||||
f"--package='{' '.join(values['packages'])}'"
|
||||
])
|
||||
# FIXME : we're feeding the raw value of values['packages'] to the helper .. if we want to be consistent, may they should be comma-separated, though in the majority of cases, only a single package is installed from an extra repo..
|
||||
|
||||
self._run_script("provision_or_update", "\n".join(script))
|
||||
self._run_script("provision_or_update", script)
|
||||
|
||||
def deprovision(self, context: Dict = {}):
|
||||
self._run_script("deprovision", "ynh_remove_app_dependencies")
|
||||
|
@ -1166,7 +1175,7 @@ class PortsResource(AppResource):
|
|||
port_value = self.get_setting(setting_name)
|
||||
if not port_value and name != "main":
|
||||
# Automigrate from legacy setting foobar_port (instead of port_foobar)
|
||||
legacy_setting_name = "{name}_port"
|
||||
legacy_setting_name = f"{name}_port"
|
||||
port_value = self.get_setting(legacy_setting_name)
|
||||
if port_value:
|
||||
self.set_setting(setting_name, port_value)
|
||||
|
|
Loading…
Add table
Reference in a new issue