From 9d1a5d1924dbfe73595dab28b3a73b3bcb54b023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4rlocher?= Date: Tue, 26 May 2026 15:06:58 +0200 Subject: [PATCH 1/3] fix(send): self-review fixes (FQCN, min_ansible_version str) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * tasks/main.yml: prefix all builtin modules with ansible.builtin (file, template) — silences ansible-lint fqcn[action-core] and matches the convention used by the other roles in this collection. * meta/main.yml: change min_ansible_version from the float 2.14 to the string '2.14'. ansible-galaxy's schema requires a string here (ansible-lint schema[meta] complains otherwise — same fix I just applied to the opnform role). --- roles/send/meta/main.yml | 2 +- roles/send/tasks/main.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/send/meta/main.yml b/roles/send/meta/main.yml index 79dedb1..20f9e67 100644 --- a/roles/send/meta/main.yml +++ b/roles/send/meta/main.yml @@ -4,7 +4,7 @@ galaxy_info: description: Deploy a self-hosted Send (timvisee fork) instance with Redis via Docker Compose license: MIT - min_ansible_version: 2.14 + min_ansible_version: "2.14" galaxy_tags: - send diff --git a/roles/send/tasks/main.yml b/roles/send/tasks/main.yml index c79405a..9ed8dd8 100644 --- a/roles/send/tasks/main.yml +++ b/roles/send/tasks/main.yml @@ -3,20 +3,20 @@ # tasks file for send - name: Create docker compose directory - file: + ansible.builtin.file: path: "{{ send_docker_compose_dir }}" state: directory mode: '0755' - name: Create local upload directory - file: + ansible.builtin.file: path: "{{ send_docker_volume_dir }}/uploads" state: directory mode: '0755' when: send_storage_backend == "local" - name: Create docker-compose file for send - template: + ansible.builtin.template: src: docker-compose.yml.j2 dest: "{{ send_docker_compose_dir }}/docker-compose.yml" mode: '0644' From 5ce2a8f7375e0f804a99fdb48f22f156d290cee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4rlocher?= Date: Tue, 26 May 2026 15:07:07 +0200 Subject: [PATCH 2/3] fix(send): use Traefik v3 OR-syntax for multi-domain Host rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The router rule joined send_domains with ', ' which is the v2 syntax ('Host(`a`, `b`)'). Traefik v3 expects each Host() to be its own matcher joined with the explicit '||' OR operator. With v3 the comma form is silently ignored — only the first host actually matches. Match the pattern already used in the authentik, drawio and nextcloud roles in this collection. --- roles/send/templates/docker-compose.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/send/templates/docker-compose.yml.j2 b/roles/send/templates/docker-compose.yml.j2 index a6733bb..69a43ab 100644 --- a/roles/send/templates/docker-compose.yml.j2 +++ b/roles/send/templates/docker-compose.yml.j2 @@ -45,7 +45,7 @@ services: labels: - traefik.enable=true - traefik.docker.network={{ send_traefik_network }} - - traefik.http.routers.{{ send_service_name }}.rule=Host({% for d in send_domains %}`{{ d }}`{% if not loop.last %}, {% endif %}{% endfor %}) + - traefik.http.routers.{{ send_service_name }}.rule={% for d in send_domains %}Host(`{{ d }}`){% if not loop.last %} || {% endif %}{% endfor +%} - traefik.http.services.{{ send_service_name }}.loadbalancer.server.port={{ send_port }} {% if send_use_ssl %} - traefik.http.routers.{{ send_service_name }}.entrypoints=websecure From d526ec382dca1d3ae70247c6a388c0ece2a087ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4rlocher?= Date: Tue, 26 May 2026 15:07:17 +0200 Subject: [PATCH 3/3] docs(send): add meta/argument_specs.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 29 typed options with full defaults coverage (no required: true marks — the role works with an empty S3 config when storage_backend=local). Documents the send_domains list convention, the local-vs-s3 storage choice, the timing/size limits and the Traefik / network wiring. Loads through ansible-core's ArgumentSpecValidator. Matches the spec convention used by the other roles in this collection. --- roles/send/meta/argument_specs.yml | 122 +++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 roles/send/meta/argument_specs.yml diff --git a/roles/send/meta/argument_specs.yml b/roles/send/meta/argument_specs.yml new file mode 100644 index 0000000..2e9797e --- /dev/null +++ b/roles/send/meta/argument_specs.yml @@ -0,0 +1,122 @@ +--- +argument_specs: + main: + short_description: Deploy timvisee/send (file-sharing) with a Redis backend via Docker Compose. + description: + - Renders a Compose stack with the C(timvisee/send) container and a + Redis companion behind Traefik. Storage can be local-disk or any + S3-compatible backend (e.g. the C(garage) role). + - Uses the shared C(*_domains) list convention so the router can + accept internal C(*.int.*) hostnames alongside the canonical + BASE_URL host. + options: + docker_compose_base_dir: + type: path + default: /etc/docker/compose + docker_volume_base_dir: + type: path + default: /srv/data + send_service_name: + type: str + default: send + send_docker_compose_dir: + type: path + send_docker_volume_dir: + type: path + + send_domains: + type: list + elements: str + default: ['send.local.test'] + description: + - FQDNs the router accepts. First entry is the canonical hostname + and is used as C(BASE_URL). Further entries cover internal + C(*.int.*) names so backend uploads can hit Send without + hairpinning via the DMZ. + send_image: + type: str + default: "registry.gitlab.com/timvisee/send:latest" + send_port: + type: int + default: 1443 + send_extra_hosts: + type: list + elements: str + default: [] + description: C(extra_hosts) entries injected into the send container (Docker C(host:ip) syntax). + + send_redis_image: + type: str + default: "redis:7-alpine" + send_redis_service_name: + type: str + default: send-redis + + send_max_file_size: + type: int + default: 1073741824 + description: Max upload size in bytes. Default is 1 GiB. + send_default_downloads: + type: int + default: 1 + send_max_downloads: + type: int + default: 100 + send_default_expire_seconds: + type: int + default: 86400 + description: Default share lifetime in seconds (24 h). + send_max_expire_seconds: + type: int + default: 604800 + description: Maximum share lifetime in seconds (7 d). + send_max_files_per_archive: + type: int + default: 64 + send_download_counts: + type: str + default: "1,2,3,4,5,20,50,100" + description: Comma-separated list of download-count options shown in the UI. + send_expire_times_seconds: + type: str + default: "300,3600,86400,604800" + description: Comma-separated list of expire-time options (seconds) shown in the UI. + + send_storage_backend: + type: str + choices: [local, s3] + default: local + description: + - C(local) keeps uploads in a host volume. C(s3) uses an + S3-compatible backend (any of the C(send_s3_*) variables is + required when this is set). + + send_s3_endpoint: + type: str + default: '' + send_s3_bucket: + type: str + default: '' + send_s3_region: + type: str + default: us-east-1 + send_s3_access_key: + type: str + default: '' + send_s3_secret_key: + type: str + default: '' + send_s3_use_path_style: + type: bool + default: true + description: Required for most non-AWS S3-compatible backends (Garage, MinIO). + + send_traefik_network: + type: str + default: proxy + send_internal_network: + type: str + default: send_internal + send_use_ssl: + type: bool + default: true