Every script a role ships now lives under `files/<language>/`, and the unit
suite is split the same way: `tests/unit/python/` beside new sibling trees for
the other languages. `tests/lint/filesystem/test_role_files_layout.py` keeps it
that way; directories whose shape is dictated from outside carry a `.nocheck`
naming the constraint (Docker build contexts, WordPress mu-plugins, the Joomla
extension, Odoo addons, Playwright suites, the `files/test/test.sh` harness
that `test-e2e-cli` resolves generically).
This cannot be applied in halves. Moving a file and repointing what names it
are the same change: 14 references resolve only at deploy time, so the tree is
green either before or after, never between.
Those 14 were found by static resolution over every reference class, not by the
test suite -- a full `make quality-high` was green while all of them were
broken:
* 7 `src:` values built from a role variable holding a bare filename
(svc-bkp-remote-2-local, decidim, espocrm, friendica, joomla, pixelfed x2).
The variable doubles as the destination name inside the container, so the
language segment belongs at the call site, not in the variable.
* `sys-service/tasks/04_base.yml` resolved every consumer's systemd script
through `first_found(..., errors='strict')` over `files/script.{sh,py}`.
18 roles ship exactly that and have no template fallback: the play would
have died on each.
* `sys-front-inj-javascript` fell back to `<role>/files/javascript.js`; the
interface now reads `files/javascript/javascript.js`.
* `sys-front-inj-logout/templates/head_sub.j2` built the cache-busting mtime
path through `path_absolute(... 'files', ...)`.
* 4 `ansible.builtin.script:` invocations naming a bare command
(pull.py, prune.sh, set_postgres_superuser_password.sh, ganesha-serve.sh).
* `dev-python/files/shell/install.sh` pointed at a sibling role's script.
Depth-dependent paths inside the moved trees were bumped accordingly: 59
`parents[N]` computations, 12 relative climbs, and the per-role recover CLI,
whose path `cli/administration/recover/recoverers.py` still assembled from the
pre-move location.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The upstream entrypoint rsyncs VERSION early inside the flock critical section it holds through the whole autoinstall, so non-slot-1 tasks passed the version-only gate mid-install, hit the still-held lock and died with an instant EIO from the blocking flock over the soft NFSv4 mount (six tasks inside slot 1's 45s install window). Strengthen the gate: require the config file and a non-blocking flock probe (single lock RPC, any error treated as not-ready) on top of the version match, which also covers the post-upgrade dbstructure window. The config path now flows from the FRIENDICA_CONFIG_FILE var through the compose environment into the gate and both container-side PHP helpers instead of three hardcoded copies.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Remove stale 0-byte ldapauth.config.php leftover when LDAP is disabled
in a matrix variant (docker bind-mount target survives in the html
volume after the bind mount is dropped, breaking bin/console).
- Force bin/console dbstructure update before addon sync; matrix variant
rounds can leave the friendica html volume's local.config.php in place
while the shared MariaDB has been re-provisioned without the friendica
tables, so addon enable then writes to non-existent tables and the
next playwright login times out.
- Add autoload-aware probe_hook_table.php; the previous inline PHP probe
always returned rc=255 on Friendica\\Module\\Register::OPEN and only
worked accidentally as a 120s sleep via retries.
- Reorganize role files into files/php/ + files/shell/ subdirs and drop
the multi-line explanatory comments now that the why-lines live in the
commit body.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>