mirror of
https://github.com/spantaleev/matrix-docker-ansible-deploy.git
synced 2026-09-09 17:33:14 +00:00
Not for merging as-is. One role's scenario plus the workflow that would make per-role testing affordable here, so we can see how it behaves before deciding whether to do the other 69. Unlike the MASH repositories, one repository holds every role, so running everything on every push is not an option. The workflow's first job works out which roles a push touched and builds the matrix from that; a change to docs, or to a role with no scenario yet, runs nothing. Three things this role needed that a MASH role does not: - The variables matrix-base would supply (matrix_base_data_path, matrix_domain, matrix_user_name, matrix_group_name and the uid/gid) have to be provided by the scenario, and the user and group have to exist before the role's file tasks run. - The service contacts the homeserver while starting up - it fetches /_matrix/client/v3/joined_rooms to resolve its room mapping and exits 1 if that fails - so prepare.yml stands up a stub homeserver. Most roles here are bridges and bots, so this is likely the rule rather than the exception. - verify.yml runs as its own play, where role defaults are out of scope, so the paths it reads are pinned in molecule.yml. The version is deliberately NOT pinned: it is read from defaults/main.yml so the assertion compares the running image against what the role ships. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
175 lines
8.1 KiB
YAML
175 lines
8.1 KiB
YAML
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
|
#
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
---
|
|
- name: Verify matrix-alertmanager-receiver
|
|
hosts: all
|
|
become: true
|
|
gather_facts: false
|
|
|
|
tasks:
|
|
# The version is read out of the role's own defaults rather than pinned in
|
|
# molecule.yml, so that the assertion further down compares the running
|
|
# image against what defaults/main.yml actually ships. Pinning it here
|
|
# would make that assertion compare the scenario with itself.
|
|
- name: Load the role's defaults under a separate name
|
|
ansible.builtin.include_vars:
|
|
file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml"
|
|
name: matrix_alertmanager_receiver_role_defaults
|
|
|
|
- name: Wait for the matrix-alertmanager-receiver service to become active
|
|
ansible.builtin.systemd_service:
|
|
name: matrix-alertmanager-receiver.service
|
|
register: matrix_alertmanager_receiver_service
|
|
until: matrix_alertmanager_receiver_service.status.ActiveState == 'active'
|
|
retries: 30
|
|
delay: 5
|
|
failed_when: false
|
|
|
|
# `Restart=always` means a crash-looping container still reports `active`,
|
|
# so the restart counter is checked alongside it. Asserted as `is defined`
|
|
# too, because `| int` turns a missing property into 0 and would pass
|
|
# vacuously on a systemd that does not expose it.
|
|
- name: Assert the service is active and has not been restarting
|
|
ansible.builtin.assert:
|
|
that:
|
|
- matrix_alertmanager_receiver_service.status.ActiveState == 'active'
|
|
- matrix_alertmanager_receiver_service.status.NRestarts is defined
|
|
- matrix_alertmanager_receiver_service.status.NRestarts | int == 0
|
|
fail_msg: >-
|
|
matrix-alertmanager-receiver.service is
|
|
{{ matrix_alertmanager_receiver_service.status.ActiveState | default('unknown') }}
|
|
after {{ matrix_alertmanager_receiver_service.status.NRestarts | default('?') }}
|
|
automatic restart(s)
|
|
success_msg: "matrix-alertmanager-receiver.service is active and has not restarted"
|
|
|
|
# Probed from inside the container network rather than from the host: the
|
|
# role publishes no host port, exactly as it does in a real deployment,
|
|
# where Traefik reaches it over the network instead.
|
|
- name: Wait for matrix-alertmanager-receiver to answer on the port the role configured
|
|
ansible.builtin.command:
|
|
argv:
|
|
- docker
|
|
- run
|
|
- --rm
|
|
- --network={{ matrix_alertmanager_receiver_container_network }}
|
|
- docker.io/curlimages/curl:8.11.1
|
|
- --silent
|
|
- --show-error
|
|
- --write-out
|
|
- "\nHTTP_STATUS=%{http_code}"
|
|
- "http://matrix-alertmanager-receiver:{{ matrix_alertmanager_receiver_config_http_port }}{{ matrix_alertmanager_receiver_config_http_metrics_path }}"
|
|
register: matrix_alertmanager_receiver_metrics
|
|
changed_when: false
|
|
until: "'HTTP_STATUS=200' in matrix_alertmanager_receiver_metrics.stdout"
|
|
retries: 24
|
|
delay: 5
|
|
failed_when: false
|
|
|
|
# The port and the metrics path are both non-default in this scenario, so a
|
|
# 200 here is only reachable if the configuration the role rendered is what
|
|
# the process is actually running on.
|
|
- name: Assert the configured port and metrics path reached the process
|
|
ansible.builtin.assert:
|
|
that:
|
|
- "'HTTP_STATUS=200' in matrix_alertmanager_receiver_metrics.stdout"
|
|
fail_msg: >-
|
|
matrix-alertmanager-receiver did not serve metrics on port
|
|
{{ matrix_alertmanager_receiver_config_http_port }} at
|
|
{{ matrix_alertmanager_receiver_config_http_metrics_path }}
|
|
({{ matrix_alertmanager_receiver_metrics.stdout | default('no output') }})
|
|
success_msg: >-
|
|
matrix-alertmanager-receiver serves metrics on the configured port and path
|
|
|
|
- name: Assert the metrics endpoint is really Prometheus metrics
|
|
ansible.builtin.assert:
|
|
that:
|
|
- "'# HELP' in matrix_alertmanager_receiver_metrics.stdout"
|
|
fail_msg: >-
|
|
The metrics endpoint answered, but did not return Prometheus metrics
|
|
success_msg: "The metrics endpoint returns Prometheus metrics"
|
|
|
|
# A negative control for the assertion above: the role's own default metrics
|
|
# path must NOT answer, or a 200 on the configured path would prove nothing
|
|
# about the configuration having been applied.
|
|
- name: Ask for the role's default metrics path, which this scenario moved away from
|
|
ansible.builtin.command:
|
|
argv:
|
|
- docker
|
|
- run
|
|
- --rm
|
|
- --network={{ matrix_alertmanager_receiver_container_network }}
|
|
- docker.io/curlimages/curl:8.11.1
|
|
- --silent
|
|
- --output
|
|
- /dev/null
|
|
- --write-out
|
|
- "HTTP_STATUS=%{http_code}"
|
|
- "http://matrix-alertmanager-receiver:{{ matrix_alertmanager_receiver_config_http_port }}/metrics"
|
|
register: matrix_alertmanager_receiver_default_path
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Assert the default metrics path does not answer
|
|
ansible.builtin.assert:
|
|
that:
|
|
- "'HTTP_STATUS=200' not in matrix_alertmanager_receiver_default_path.stdout"
|
|
fail_msg: >-
|
|
/metrics answered as well, so serving on
|
|
{{ matrix_alertmanager_receiver_config_http_metrics_path }} does not
|
|
prove the role's configuration reached the process
|
|
({{ matrix_alertmanager_receiver_default_path.stdout | default('no output') }})
|
|
success_msg: "Only the configured metrics path answers"
|
|
|
|
- name: Read the configuration file the role rendered
|
|
ansible.builtin.slurp:
|
|
src: "{{ matrix_alertmanager_receiver_config_path }}/config.yml"
|
|
register: matrix_alertmanager_receiver_config_file
|
|
|
|
- name: Assert the rendered configuration carries this scenario's values
|
|
ansible.builtin.assert:
|
|
that:
|
|
- matrix_alertmanager_receiver_config_matrix_user_id in matrix_alertmanager_receiver_config_rendered
|
|
- matrix_alertmanager_receiver_config_matrix_access_token in matrix_alertmanager_receiver_config_rendered
|
|
- "'molecule-room' in matrix_alertmanager_receiver_config_rendered"
|
|
fail_msg: "The rendered configuration does not carry the scenario's Matrix settings"
|
|
success_msg: "The rendered configuration carries the scenario's Matrix settings"
|
|
vars:
|
|
matrix_alertmanager_receiver_config_rendered: "{{ matrix_alertmanager_receiver_config_file.content | b64decode }}"
|
|
|
|
- name: Assert the running container is the image the role pins
|
|
ansible.builtin.command:
|
|
argv:
|
|
- docker
|
|
- container
|
|
- inspect
|
|
- matrix-alertmanager-receiver
|
|
- --format
|
|
- "{{ '{{' }} .Config.Image {{ '}}' }}"
|
|
register: matrix_alertmanager_receiver_image
|
|
changed_when: false
|
|
|
|
- name: Assert the image carries the version defaults/main.yml pins
|
|
ansible.builtin.assert:
|
|
that:
|
|
- matrix_alertmanager_receiver_role_defaults.matrix_alertmanager_receiver_version in matrix_alertmanager_receiver_image.stdout
|
|
fail_msg: >-
|
|
The running container is {{ matrix_alertmanager_receiver_image.stdout }},
|
|
which does not carry the pinned version {{ matrix_alertmanager_receiver_role_defaults.matrix_alertmanager_receiver_version }}
|
|
success_msg: "The running container is the version defaults/main.yml pins"
|
|
|
|
- name: Read the labels the role rendered
|
|
ansible.builtin.slurp:
|
|
src: "{{ matrix_alertmanager_receiver_base_path }}/labels"
|
|
register: matrix_alertmanager_receiver_labels
|
|
|
|
- name: Assert no Traefik labels are emitted while Traefik support is disabled
|
|
ansible.builtin.assert:
|
|
that:
|
|
- "'traefik.' not in (matrix_alertmanager_receiver_labels.content | b64decode)"
|
|
fail_msg: >-
|
|
Traefik labels were emitted even though
|
|
matrix_alertmanager_receiver_container_labels_traefik_enabled is false
|
|
success_msg: "No Traefik labels are emitted while Traefik support is disabled"
|