mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
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>
81 lines
3.5 KiB
Django/Jinja
81 lines
3.5 KiB
Django/Jinja
{% include 'roles/sys-svc-container/templates/env.j2' %}
|
|
|
|
BOOKWYRM_URL={{ BOOKWYRM_URL }}
|
|
DOMAIN={{ BOOKWYRM_HOSTNAME }}
|
|
ALLOWED_HOSTS={{ BOOKWYRM_HOSTNAME }},127.0.0.1,localhost
|
|
PORT={{ lookup('tls', application_id, 'ports.web') }}
|
|
TLS_ENABLED={{ lookup('tls', application_id, 'protocols.web') }}
|
|
MEDIA_ROOT={{ lookup('volume', 'web-app-bookwyrm', 'media').target }}
|
|
DATA_ROOT={{ lookup('volume', 'web-app-bookwyrm', 'data').target }}
|
|
REGISTRATION_OPEN={{ BOOKWYRM_REGISTRATION_OPEN }}
|
|
ALLOW_INVITE_REQUESTS={{ BOOKWYRM_ALLOW_INVITE_REQUESTS }}
|
|
|
|
PROXY_HEADER_SSO={{ BOOKWYRM_SSO_PROXY_GATED | string | lower }}
|
|
|
|
{% if lookup('objstore', application_id, 'enabled') | bool %}
|
|
USE_S3=true
|
|
AWS_ACCESS_KEY_ID={{ lookup('objstore', application_id, 'access_key') }}
|
|
AWS_SECRET_ACCESS_KEY={{ lookup('objstore', application_id, 'secret_key') }}
|
|
AWS_STORAGE_BUCKET_NAME={{ lookup('objstore', application_id, 'bucket') }}
|
|
AWS_S3_ENDPOINT_URL={{ lookup('objstore', application_id, 'url') }}
|
|
AWS_S3_REGION_NAME={{ lookup('objstore', application_id, 'region') }}
|
|
AWS_S3_CUSTOM_DOMAIN={{ lookup('objstore', application_id, 'public_bucket') }}
|
|
USE_S3_FOR_EXPORTS=false
|
|
{% else %}
|
|
USE_S3=false
|
|
{% endif %}
|
|
|
|
SECRET_KEY={{ BOOKWYRM_SECRET_KEY }}
|
|
|
|
EMAIL_HOST={{ EMAIL_HOST }}
|
|
EMAIL_PORT={{ EMAIL_PORT }}
|
|
EMAIL_USE_TLS={{ EMAIL_USE_TLS }}
|
|
EMAIL_USE_SSL={{ EMAIL_USE_SSL }}
|
|
EMAIL_HOST_USER={{ EMAIL_HOST_USER }}
|
|
EMAIL_HOST_PASSWORD={{ EMAIL_HOST_PASSWORD | dotenv_quote }}
|
|
DEFAULT_FROM_EMAIL={{ EMAIL_DEFAULT_FROM }}
|
|
|
|
POSTGRES_DB={{ lookup('database', application_id, 'name') }}
|
|
POSTGRES_USER={{ lookup('database', application_id, 'username') }}
|
|
POSTGRES_PASSWORD={{ lookup('database', application_id, 'password') | dotenv_quote }}
|
|
POSTGRES_HOST={{ lookup('database', application_id, 'host') }}
|
|
POSTGRES_PORT={{ lookup('database', application_id, 'port') }}
|
|
DATABASE_URL=postgres://{{ lookup('database', application_id, 'username') }}:{{ lookup('database', application_id, 'password') }}@{{ lookup('database', application_id, 'host') }}:{{ lookup('database', application_id, 'port') }}/{{ lookup('database', application_id, 'name') }}
|
|
|
|
REDIS_HOST={{ BOOKWYRM_REDIS_HOST }}
|
|
REDIS_PORT={{ BOOKWYRM_REDIS_PORT }}
|
|
REDIS_URL={{ BOOKWYRM_REDIS_CACHE_URL }}
|
|
REDIS_CACHE_URL={{ BOOKWYRM_REDIS_CACHE_URL }}
|
|
CACHE_URL={{ BOOKWYRM_REDIS_CACHE_URL }}
|
|
DJANGO_REDIS_URL={{ BOOKWYRM_REDIS_CACHE_URL }}
|
|
|
|
BROKER_URL={{ BOOKWYRM_BROKER_URL }}
|
|
REDIS_BROKER_URL={{ BOOKWYRM_REDIS_BROKER_URL }}
|
|
REDIS_BROKER_HOST={{ BOOKWYRM_REDIS_HOST }}
|
|
REDIS_BROKER_PORT={{ BOOKWYRM_REDIS_PORT }}
|
|
REDIS_BROKER_DB_INDEX={{ BOOKWYRM_REDIS_BROKER_DB }}
|
|
CELERY_BROKER_URL={{ BOOKWYRM_REDIS_BROKER_URL }}
|
|
|
|
REDIS_ACTIVITY_HOST={{ BOOKWYRM_REDIS_HOST }}
|
|
REDIS_ACTIVITY_PORT={{ BOOKWYRM_REDIS_PORT }}
|
|
REDIS_ACTIVITY_DB_INDEX={{ BOOKWYRM_REDIS_ACTIVITY_DB }}
|
|
REDIS_ACTIVITY_URL={{ BOOKWYRM_REDIS_ACTIVITY_URL }}
|
|
|
|
FORWARDED_ALLOW_IPS=*
|
|
USE_X_FORWARDED_HOST=true
|
|
SECURE_PROXY_SSL_HEADER={{ lookup('tls', application_id, 'enabled') | string | lower }}
|
|
|
|
{% if BOOKWYRM_OIDC_ENABLED %}
|
|
OIDC_TITLE={{ BOOKWYRM_OIDC_LABEL | dotenv_quote }}
|
|
OIDC_ISSUER={{ BOOKWYRM_OIDC_ISSUER }}
|
|
OIDC_AUTHORIZATION_ENDPOINT={{ BOOKWYRM_OIDC_AUTH_URL }}
|
|
OIDC_TOKEN_ENDPOINT={{ BOOKWYRM_OIDC_TOKEN_URL }}
|
|
OIDC_USERINFO_ENDPOINT={{ BOOKWYRM_OIDC_USERINFO_URL }}
|
|
OIDC_END_SESSION_ENDPOINT={{ BOOKWYRM_OIDC_LOGOUT_URL }}
|
|
OIDC_JWKS_URI={{ BOOKWYRM_OIDC_JWKS_URL }}
|
|
OIDC_CLIENT_ID={{ BOOKWYRM_OIDC_CLIENT_ID }}
|
|
OIDC_CLIENT_SECRET={{ BOOKWYRM_OIDC_CLIENT_SECRET }}
|
|
OIDC_SCOPES={{ BOOKWYRM_OIDC_SCOPES }}
|
|
OIDC_UNIQUE_ATTRIBUTE={{ BOOKWYRM_OIDC_UNIQUE_ATTRIBUTE }}
|
|
{% endif %}
|