195 lines
6.8 KiB
YAML
195 lines
6.8 KiB
YAML
---
|
|
# Service Restart Playbook
|
|
# Restart specific services with proper dependency handling
|
|
# Usage: ansible-playbook playbooks/restart_service.yml -e "service_name=plex host_target=atlantis"
|
|
# Usage: ansible-playbook playbooks/restart_service.yml -e "service_name=immich-server host_target=atlantis wait_time=30"
|
|
|
|
- name: Restart Service with Dependency Handling
|
|
hosts: "{{ host_target | default('all') }}"
|
|
gather_facts: yes
|
|
vars:
|
|
service_name: "{{ service_name | mandatory }}"
|
|
force_restart: "{{ force_restart | default(false) }}"
|
|
|
|
# Service dependency mapping
|
|
service_dependencies:
|
|
# Media stack dependencies
|
|
plex:
|
|
depends_on: []
|
|
restart_delay: 30
|
|
sonarr:
|
|
depends_on: ["prowlarr"]
|
|
restart_delay: 20
|
|
radarr:
|
|
depends_on: ["prowlarr"]
|
|
restart_delay: 20
|
|
lidarr:
|
|
depends_on: ["prowlarr"]
|
|
restart_delay: 20
|
|
bazarr:
|
|
depends_on: ["sonarr", "radarr"]
|
|
restart_delay: 15
|
|
jellyseerr:
|
|
depends_on: ["plex", "sonarr", "radarr"]
|
|
restart_delay: 25
|
|
|
|
# Immich stack
|
|
immich-server:
|
|
depends_on: ["immich-db", "immich-redis"]
|
|
restart_delay: 30
|
|
immich-machine-learning:
|
|
depends_on: ["immich-server"]
|
|
restart_delay: 20
|
|
|
|
# Security stack
|
|
vaultwarden:
|
|
depends_on: ["vaultwarden-db"]
|
|
restart_delay: 25
|
|
|
|
# Monitoring stack
|
|
grafana:
|
|
depends_on: ["prometheus"]
|
|
restart_delay: 20
|
|
prometheus:
|
|
depends_on: []
|
|
restart_delay: 30
|
|
|
|
tasks:
|
|
- name: Validate required variables
|
|
fail:
|
|
msg: "service_name is required. Use -e 'service_name=SERVICE_NAME'"
|
|
when: service_name is not defined or service_name == ""
|
|
|
|
- name: Check if Docker is running
|
|
systemd:
|
|
name: docker
|
|
register: docker_status
|
|
failed_when: docker_status.status.ActiveState != "active"
|
|
|
|
- name: Check if service exists
|
|
shell: 'docker ps -a --filter "name={{ service_name }}" --format "{%raw%}{{.Names}}{%endraw%}"'
|
|
register: service_exists
|
|
changed_when: false
|
|
|
|
- name: Fail if service doesn't exist
|
|
fail:
|
|
msg: "Service '{{ service_name }}' not found on {{ inventory_hostname }}"
|
|
when: service_exists.stdout == ""
|
|
|
|
- name: Get current service status
|
|
shell: 'docker ps --filter "name={{ service_name }}" --format "{%raw%}{{.Status}}{%endraw%}"'
|
|
register: service_status_before
|
|
changed_when: false
|
|
|
|
- name: Display pre-restart status
|
|
debug:
|
|
msg: |
|
|
🔄 RESTART REQUEST for {{ service_name }} on {{ inventory_hostname }}
|
|
📊 Current Status: {{ service_status_before.stdout | default('Not running') }}
|
|
⏱️ Wait Time: {{ wait_time | default(15) }} seconds
|
|
🔗 Dependencies: {{ service_dependencies.get(service_name, {}).get('depends_on', []) | join(', ') or 'None' }}
|
|
|
|
- name: Check dependencies are running
|
|
shell: 'docker ps --filter "name={{ item }}" --format "{%raw%}{{.Names}}{%endraw%}"'
|
|
register: dependency_check
|
|
loop: "{{ service_dependencies.get(service_name, {}).get('depends_on', []) }}"
|
|
when: service_dependencies.get(service_name, {}).get('depends_on', []) | length > 0
|
|
|
|
- name: Warn about missing dependencies
|
|
debug:
|
|
msg: "⚠️ Warning: Dependency '{{ item.item }}' is not running"
|
|
loop: "{{ dependency_check.results | default([]) }}"
|
|
when:
|
|
- dependency_check is defined
|
|
- item.stdout == ""
|
|
|
|
- name: Create pre-restart backup of logs
|
|
shell: |
|
|
mkdir -p /tmp/service_logs/{{ ansible_date_time.date }}
|
|
docker logs {{ service_name }} --tail 100 > /tmp/service_logs/{{ ansible_date_time.date }}/{{ service_name }}_pre_restart.log 2>&1
|
|
ignore_errors: yes
|
|
|
|
- name: Stop service gracefully
|
|
shell: docker stop {{ service_name }}
|
|
register: stop_result
|
|
ignore_errors: yes
|
|
|
|
- name: Force stop if graceful stop failed
|
|
shell: docker kill {{ service_name }}
|
|
when:
|
|
- stop_result.rc != 0
|
|
- force_restart | bool
|
|
|
|
- name: Wait for service to fully stop
|
|
shell: 'docker ps --filter "name={{ service_name }}" --format "{%raw%}{{.Names}}{%endraw%}"'
|
|
register: stop_check
|
|
until: stop_check.stdout == ""
|
|
retries: 10
|
|
delay: 2
|
|
|
|
- name: Start service
|
|
shell: docker start {{ service_name }}
|
|
register: start_result
|
|
|
|
- name: Wait for service to be ready
|
|
pause:
|
|
seconds: "{{ service_dependencies.get(service_name, {}).get('restart_delay', wait_time | default(15)) }}"
|
|
|
|
- name: Verify service is running
|
|
shell: 'docker ps --filter "name={{ service_name }}" --format "{%raw%}{{.Status}}{%endraw%}"'
|
|
register: service_status_after
|
|
retries: 5
|
|
delay: 3
|
|
until: "'Up' in service_status_after.stdout"
|
|
|
|
- name: Check service health (if health check available)
|
|
shell: 'docker inspect {{ service_name }} --format="{%raw%}{{.State.Health.Status}}{%endraw%}"'
|
|
register: health_check
|
|
ignore_errors: yes
|
|
changed_when: false
|
|
|
|
- name: Wait for healthy status
|
|
shell: 'docker inspect {{ service_name }} --format="{%raw%}{{.State.Health.Status}}{%endraw%}"'
|
|
register: health_status
|
|
until: health_status.stdout == "healthy"
|
|
retries: 10
|
|
delay: 5
|
|
when:
|
|
- health_check.rc == 0
|
|
- health_check.stdout != "none"
|
|
ignore_errors: yes
|
|
|
|
- name: Create post-restart log snapshot
|
|
shell: |
|
|
docker logs {{ service_name }} --tail 50 > /tmp/service_logs/{{ ansible_date_time.date }}/{{ service_name }}_post_restart.log 2>&1
|
|
ignore_errors: yes
|
|
|
|
- name: Display restart results
|
|
debug:
|
|
msg: |
|
|
|
|
✅ SERVICE RESTART COMPLETE
|
|
================================
|
|
🖥️ Host: {{ inventory_hostname }}
|
|
🔧 Service: {{ service_name }}
|
|
📊 Status Before: {{ service_status_before.stdout | default('Not running') }}
|
|
📊 Status After: {{ service_status_after.stdout }}
|
|
{% if health_check.rc == 0 and health_check.stdout != "none" %}
|
|
🏥 Health Status: {{ health_status.stdout | default('Checking...') }}
|
|
{% endif %}
|
|
⏱️ Restart Duration: {{ service_dependencies.get(service_name, {}).get('restart_delay', wait_time | default(15)) }} seconds
|
|
📝 Logs: /tmp/service_logs/{{ ansible_date_time.date }}/{{ service_name }}_*.log
|
|
|
|
================================
|
|
|
|
- name: Restart dependent services (if any)
|
|
include_tasks: restart_dependent_services.yml
|
|
vars:
|
|
parent_service: "{{ service_name }}"
|
|
when: restart_dependents | default(false) | bool
|
|
|
|
handlers:
|
|
- name: restart_dependent_services
|
|
debug:
|
|
msg: "This would restart services that depend on {{ service_name }}"
|