Files
computer-playbook/roles/web-app-xwiki/vars/main.yml
kevinveenbirkenbachandClaude Opus 5 29015311b6 feat(lint): derive container paths from meta/volumes.yml everywhere
meta/volumes.yml says where a volume lands inside its container. Wherever a
second file spelled the same path out, the two drifted independently: the mount
moves, the consumer keeps pointing at the old place, and nothing fails until the
process looks for content that is not there. e031b7f61 fixed exactly this for
web-app-moodle; this generalises it and makes the rule hold.

The lookup gains what a caller needs. `targets` maps each mounting service to
its container path, and `target` is the one path an entry mounts at -- present
only when every mount agrees. An entry that lands at different paths per service
omits `target` rather than picking one, and the caller names the service:

    "{{ lookup('volume', application_id, 'prometheus_config').target }}"
    "{{ lookup('volume', 'web-app-prometheus', 'host_sys').targets['node-exporter'] }}"

66 literals across 48 role files now derive. Replacement only happened where the
path stood alone -- /srv/app inside /srv/app/data is a different path -- and
every rewritten file was re-parsed, Jinja and YAML alike. Three sites the tool
refused rather than guess were done by hand: zammad's path sat in a Jinja list
literal, seaweedfs' inside a quoted string feeding a filter, and openresty's
/var/run/docker.sock is not a mount target at all but the socket on the host,
which only happens to spell the same string. That one carries the single
nocheck.

tests/lint/repository/spot/test_volumes_path_single_spot.py keeps it that way.
roles/*/files/ is out of scope by construction: it is copied verbatim into an
image and executed there, so a Dockerfile or entrypoint has no Ansible to
evaluate a lookup with.

One defect this found, and it was in the tooling rather than the roles: deciding
ambiguity AFTER filtering short paths made web-app-prometheus' host_sys look
single-valued -- it mounts /sys for cadvisor and /host/sys for node-exporter,
and /sys is below the length filter. The template would have rendered an
undefined `.target`. Both the converter and the rule now decide ambiguity over
every target and filter afterwards, and that call reads targets['node-exporter'].

Verified by resolving rather than by reading: all 70 accesses in the diff were
run against the real registry and every one yields a non-empty path equal to the
literal it replaced. make test-lint: 328 passed.

Not verified: no Ansible render, so a call site whose surrounding context cannot
build the applications registry would still fail at deploy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 02:02:29 +02:00

58 lines
3.0 KiB
YAML

---
application_id: "web-app-xwiki"
entity_name: "{{ application_id | get_entity_name }}"
domain: "{{ lookup('domain',application_id) }}"
container_hostname: "{{ lookup('container_hostname', application_id) }}"
XWIKI_HOST_PORT: "{{ lookup('config', application_id, 'services.xwiki.ports.local.http') }}"
XWIKI_HOSTNAME: "{{ container_hostname }}"
XWIKI_HOST_PROPERTIES_PATH: "{{ [lookup('container', application_id, 'directories.config'), 'xwiki.properties'] | path_join }}"
XWIKI_DOCK_DATA_DIR: "{{ lookup('volume', 'web-app-xwiki', 'data').target }}"
XWIKI_IMAGE: "{{ lookup('config', application_id, 'services.xwiki.image') }}"
XWIKI_VERSION: "{{ lookup('config', application_id, 'services.xwiki.version') }}"
XWIKI_CONTAINER: "{{ lookup('config', application_id, 'services.xwiki.name') }}"
XWIKI_CONTAINER_ADDRESS: "{{ lookup('container_address', application_id, entity_name) }}"
XWIKI_LDAP_ENABLED: "{{ lookup('config', application_id, 'services.ldap.enabled') }}"
XWIKI_OIDC_ENABLED: "{{ lookup('config', application_id, 'services.sso.enabled') }}"
XWIKI_SSO_ENABLED: "{{ (XWIKI_OIDC_ENABLED | bool) or (XWIKI_LDAP_ENABLED | bool) }}"
XWIKI_ADMIN_USER: "{{ lookup('users', 'administrator').username }}"
XWIKI_ADMIN_GROUP: "administrator"
XWIKI_ADMIN_GROUP_PAGE: "XWikiAdminGroup"
XWIKI_SUPERADMIN_PASSWORD: "{{ lookup('config', application_id, 'secrets.credentials.superadminpassword') }}"
XWIKI_SUPERADMIN_USERNAME: "superadmin"
XWIKI_DOCKER_REACH_URL: "http://{{ DOCKER_REACH_HOST }}:{{ XWIKI_HOST_PORT }}"
XWIKI_REST_BASE: "{{ [XWIKI_DOCKER_REACH_URL, '/rest/'] | url_join }}"
XWIKI_REST_XWIKI: "{{ [XWIKI_REST_BASE, 'wikis/xwiki'] | url_join }}"
XWIKI_REST_XWIKI_PAGES: "{{ [XWIKI_REST_BASE, 'wikis/xwiki/spaces/XWiki/pages'] | url_join }}"
XWIKI_LDAP_SERVER: "{{ LDAP.SERVER.DOMAIN }}"
XWIKI_LDAP_PORT: "{{ LDAP.SERVER.PORT }}"
XWIKI_LDAP_BASE_DN: "{{ LDAP.DN.ROOT }}"
XWIKI_LDAP_BIND_DN: "{{ LDAP.DN.ADMINISTRATOR.DATA }}"
XWIKI_LDAP_BIND_PASS: "{{ LDAP.BIND_CREDENTIAL }}"
XWIKI_LDAP_TRYLOCAL: "{{ lookup('config', application_id, 'services.ldap.trylocal') }}"
XWIKI_LDAP_FIELDS_MAPPING: "last_name={{ LDAP.USER.ATTRIBUTES.SURNAME }},first_name={{ LDAP.USER.ATTRIBUTES.FIRSTNAME }},email={{ LDAP.USER.ATTRIBUTES.MAIL }}"
XWIKI_LDAP_ADMIN_GROUP_DN: "cn={{ XWIKI_ADMIN_GROUP }},ou={{ application_id }},{{ LDAP.DN.OU.ROLES }}"
XWIKI_OIDC_PROVIDER: "{{ OIDC.CLIENT.ISSUER_URL }}"
XWIKI_OIDC_AUTHORIZATION: "{{ OIDC.CLIENT.AUTHORIZE_URL }}"
XWIKI_OIDC_TOKEN: "{{ OIDC.CLIENT.TOKEN_URL }}"
XWIKI_OIDC_USERINFO: "{{ OIDC.CLIENT.USER_INFO_URL }}"
XWIKI_OIDC_LOGOUT: "{{ OIDC.CLIENT.LOGOUT_URL }}"
XWIKI_OIDC_CLIENT_ID: "{{ OIDC.CLIENT.ID }}"
XWIKI_OIDC_CLIENT_SECRET: "{{ OIDC.CLIENT.SECRET }}"
XWIKI_OIDC_SCOPES: "openid,email,profile,{{ RBAC.GROUP.CLAIM }}"
XWIKI_OIDC_GROUPS_CLAIM: "{{ RBAC.GROUP.CLAIM }}"
XWIKI_OIDC_ADMIN_PROVIDER_GROUP: "{{ lookup('rbac_group_path', application_id=application_id, role='administrator') }}"
XWIKI_PLUGINS: "{{ lookup('config', application_id, 'addons') | xwiki_enabled_install_items }}"