Run from the jump host: on each validator it updates the git clone in /opt/cloud-ip-validator, builds the image there, stops and removes the current container and starts a new one from the new image. Run parameters live in an env file (deploy/ansible/env/validator-agent.env, git-ignored, template committed). The image is built before the running container is touched, so a failed build leaves the old container running. Hosts are updated in waves (1, 4, rest) and any failure stops the run. validator_id comes from the inventory and is checked against the running container before it is replaced. Only ansible.builtin modules are used, so the validators need no extra packages. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
66 lines
2.9 KiB
YAML
66 lines
2.9 KiB
YAML
---
|
|
- name: Verify the new container
|
|
block:
|
|
# Агент пишет "registered" после успешной регистрации в control-api.
|
|
- name: Wait for the agent to register in control-api
|
|
ansible.builtin.command: "docker logs --tail 200 {{ container_name }}"
|
|
register: agent_logs
|
|
changed_when: false
|
|
until: agent_logs.stdout is search('msg=registered validator_id=' ~ effective_validator_id ~ '(\s|$)') or agent_logs.stderr is search('msg=registered validator_id=' ~ effective_validator_id ~ '(\s|$)')
|
|
retries: "{{ verify_retries | int }}"
|
|
delay: "{{ verify_delay | int }}"
|
|
|
|
- name: Inspect the container
|
|
ansible.builtin.command:
|
|
argv: [docker, inspect, --format, "{% raw %}{{.State.Running}} {{.RestartCount}} {{.Image}}{% endraw %}", "{{ container_name }}"]
|
|
register: container_state
|
|
changed_when: false
|
|
|
|
- name: Check the container state
|
|
ansible.builtin.assert:
|
|
that:
|
|
- container_state.stdout.split()[0] == 'true'
|
|
- container_state.stdout.split()[1] == '0'
|
|
- container_state.stdout.split()[2] == built_image.stdout
|
|
fail_msg: >-
|
|
Контейнер {{ container_name }} в состоянии «{{ container_state.stdout }}»
|
|
(ожидалось: запущен, 0 перезапусков, образ {{ built_image.stdout }}).
|
|
quiet: true
|
|
rescue:
|
|
- name: Collect the container log
|
|
ansible.builtin.command: "docker logs --tail 30 {{ container_name }}"
|
|
register: failed_logs
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Fail the host and stop the next waves
|
|
ansible.builtin.fail:
|
|
msg: |-
|
|
{{ inventory_hostname }}: контейнер не прошёл проверку после запуска.
|
|
Последние строки лога:
|
|
{{ failed_logs.stdout }}{{ failed_logs.stderr }}
|
|
|
|
# Старые образы с метками ревизий: оставляем keep_images последних (docker
|
|
# выводит от новых к старым), образ работающего контейнера docker не удалит.
|
|
- name: List image tags
|
|
ansible.builtin.command:
|
|
argv: [docker, images, "{{ image_name }}", --format, "{% raw %}{{.Tag}}{% endraw %}"]
|
|
register: image_tags
|
|
changed_when: false
|
|
|
|
- name: Remove old revision images
|
|
ansible.builtin.command: "docker rmi {{ image_name }}:{{ item }}"
|
|
loop: "{{ (image_tags.stdout_lines | reject('equalto', 'latest') | list)[keep_images | int:] }}"
|
|
changed_when: true
|
|
failed_when: false
|
|
|
|
- name: Remove dangling images
|
|
ansible.builtin.command: docker image prune -f
|
|
changed_when: false
|
|
|
|
- name: Summary
|
|
ansible.builtin.debug:
|
|
msg: >-
|
|
{{ inventory_hostname }} ({{ effective_validator_id }}): {{ deploy_rev }} ({{ deploy_ref }}),
|
|
образ {{ built_image.stdout[:19] }}, контейнер {{ container_name }} запущен
|