mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-28 08:42:24 +01:00
Compare commits
2
Commits
3cd6cdb638
...
bec4d1805d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bec4d1805d | ||
|
|
54d794e8de |
@@ -129,7 +129,10 @@ services:
|
||||
fi
|
||||
sed "s|__SEARXNG_SECRET__|$$secret|g" /tmp/searxng-settings.yml.template > /etc/searxng/settings.yml
|
||||
fi
|
||||
/usr/local/searxng/.venv/bin/python /tmp/migrate-searxng-settings.py /etc/searxng/settings.yml
|
||||
# Advisory: a settings file the migration cannot parse or rewrite must
|
||||
# not be what stops searxng from booting. It explains itself on stderr
|
||||
# and we carry on, letting searxng report anything genuinely wrong.
|
||||
/usr/local/searxng/.venv/bin/python /tmp/migrate-searxng-settings.py /etc/searxng/settings.yml || true
|
||||
exec /usr/local/searxng/entrypoint.sh
|
||||
ports:
|
||||
- "127.0.0.1:8080:8080"
|
||||
|
||||
@@ -132,7 +132,10 @@ services:
|
||||
fi
|
||||
sed "s|__SEARXNG_SECRET__|$$secret|g" /tmp/searxng-settings.yml.template > /etc/searxng/settings.yml
|
||||
fi
|
||||
/usr/local/searxng/.venv/bin/python /tmp/migrate-searxng-settings.py /etc/searxng/settings.yml
|
||||
# Advisory: a settings file the migration cannot parse or rewrite must
|
||||
# not be what stops searxng from booting. It explains itself on stderr
|
||||
# and we carry on, letting searxng report anything genuinely wrong.
|
||||
/usr/local/searxng/.venv/bin/python /tmp/migrate-searxng-settings.py /etc/searxng/settings.yml || true
|
||||
exec /usr/local/searxng/entrypoint.sh
|
||||
ports:
|
||||
- "127.0.0.1:8080:8080"
|
||||
|
||||
+4
-1
@@ -110,7 +110,10 @@ services:
|
||||
fi
|
||||
sed "s|__SEARXNG_SECRET__|$$secret|g" /tmp/searxng-settings.yml.template > /etc/searxng/settings.yml
|
||||
fi
|
||||
/usr/local/searxng/.venv/bin/python /tmp/migrate-searxng-settings.py /etc/searxng/settings.yml
|
||||
# Advisory: a settings file the migration cannot parse or rewrite must
|
||||
# not be what stops searxng from booting. It explains itself on stderr
|
||||
# and we carry on, letting searxng report anything genuinely wrong.
|
||||
/usr/local/searxng/.venv/bin/python /tmp/migrate-searxng-settings.py /etc/searxng/settings.yml || true
|
||||
exec /usr/local/searxng/entrypoint.sh
|
||||
ports:
|
||||
- "127.0.0.1:8080:8080"
|
||||
|
||||
@@ -120,8 +120,13 @@ def migrate_settings(path: Path) -> bool:
|
||||
)
|
||||
temporary = Path(temporary_name)
|
||||
try:
|
||||
os.fchown(fd, source_stat.st_uid, source_stat.st_gid)
|
||||
# chmod before chown: the Compose cap set is `cap_drop: ALL` plus
|
||||
# CHOWN/SETGID/SETUID/DAC_OVERRIDE, with no FOWNER. Once the temporary
|
||||
# file belongs to searxng:searxng — which every retained settings file
|
||||
# does, because searxng's entrypoint chowns /etc/searxng — root can no
|
||||
# longer chmod it and the migration dies with EPERM.
|
||||
os.fchmod(fd, stat.S_IMODE(source_stat.st_mode))
|
||||
os.fchown(fd, source_stat.st_uid, source_stat.st_gid)
|
||||
with os.fdopen(fd, "wb") as handle:
|
||||
fd = -1
|
||||
handle.write(updated)
|
||||
|
||||
@@ -245,6 +245,44 @@ def test_invalid_utf8_is_not_replaced(tmp_path):
|
||||
assert after.st_ino == before.st_ino
|
||||
|
||||
|
||||
def test_temporary_file_is_chmodded_before_it_is_chowned(tmp_path, monkeypatch):
|
||||
# The Compose cap set is `cap_drop: ALL` plus CHOWN/SETGID/SETUID/
|
||||
# DAC_OVERRIDE and carries no FOWNER, and searxng's entrypoint chowns
|
||||
# /etc/searxng to searxng:searxng, so every retained settings file is owned
|
||||
# by that user. Chowning the temporary file first therefore makes the chmod
|
||||
# that follows fail with EPERM, and `set -eu` in the Compose entrypoint
|
||||
# turns that into a container that never starts. The guard below refuses
|
||||
# the chmod once the chown has landed, the way the kernel does.
|
||||
migration = _load_migration_module()
|
||||
settings = tmp_path / "settings.yml"
|
||||
settings.write_bytes(b"server:\n secret_key: retained\n")
|
||||
settings.chmod(0o640)
|
||||
calls = []
|
||||
real_fchmod = migration.os.fchmod
|
||||
real_fchown = migration.os.fchown
|
||||
|
||||
def guarded_fchmod(fd, mode):
|
||||
if "fchown" in calls:
|
||||
raise PermissionError(1, "Operation not permitted")
|
||||
calls.append("fchmod")
|
||||
return real_fchmod(fd, mode)
|
||||
|
||||
def recording_fchown(fd, uid, gid):
|
||||
calls.append("fchown")
|
||||
return real_fchown(fd, uid, gid)
|
||||
|
||||
monkeypatch.setattr(migration.os, "fchmod", guarded_fchmod)
|
||||
monkeypatch.setattr(migration.os, "fchown", recording_fchown)
|
||||
|
||||
assert migration.migrate_settings(settings) is True
|
||||
|
||||
assert calls == ["fchmod", "fchown"]
|
||||
assert stat.S_IMODE(settings.stat().st_mode) == 0o640
|
||||
assert settings.read_bytes() == (
|
||||
b"use_default_settings: true\nserver:\n secret_key: retained\n"
|
||||
)
|
||||
|
||||
|
||||
def test_replace_failure_preserves_original_and_removes_temporary_file(
|
||||
tmp_path, monkeypatch
|
||||
):
|
||||
@@ -272,9 +310,12 @@ def test_replace_failure_preserves_original_and_removes_temporary_file(
|
||||
def test_compose_runs_migration_for_all_variants(compose_file):
|
||||
text = compose_file.read_text(encoding="utf-8")
|
||||
|
||||
# The `|| true` is load-bearing: the entrypoint runs under `set -eu`, so
|
||||
# without it a settings file the migration cannot parse or rewrite stops
|
||||
# searxng from starting at all instead of merely going unmigrated.
|
||||
assert (
|
||||
"/usr/local/searxng/.venv/bin/python /tmp/migrate-searxng-settings.py "
|
||||
"/etc/searxng/settings.yml" in text
|
||||
"/etc/searxng/settings.yml || true" in text
|
||||
)
|
||||
assert (
|
||||
"./scripts/migrate_searxng_settings.py:"
|
||||
|
||||
Reference in New Issue
Block a user