Sanitized mirror from private repository - 2026-04-18 11:19:59 UTC
This commit is contained in:
194
ansible/automation/playbooks/restart_service.yml
Normal file
194
ansible/automation/playbooks/restart_service.yml
Normal file
@@ -0,0 +1,194 @@
|
||||
---
|
||||
# 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 }}"
|
||||
Reference in New Issue
Block a user