Ensure that services restart in a particular order

Currently when multiple services share a host, the
restart order is random. This is due to an unordered
dict being used to facilitate the mapping of services
to their groups, names and other options.

Based on [1], this patch implements changes to the role
to ensure that services on the same host are restarted
in the correct order when the software/config changes.

[1] https://docs.openstack.org/developer/cinder/upgrade.html#minimal-downtime-upgrade-procedure

Change-Id: If5729671cb69f928df660ec2d9ba83fe3f567946
This commit is contained in:
Jesse Pretorius 2017-06-09 14:44:57 +01:00 committed by Jesse Pretorius (odyssey4me)
parent f8f7fa0fca
commit b98100fe0c
6 changed files with 35 additions and 28 deletions

View File

@ -269,19 +269,23 @@ cinder_services:
group: cinder_api group: cinder_api
service_name: cinder-api service_name: cinder-api
init_config_overrides: "{{ cinder_api_init_overrides }}" init_config_overrides: "{{ cinder_api_init_overrides }}"
start_order: 1
cinder-scheduler: cinder-scheduler:
group: cinder_scheduler group: cinder_scheduler
service_name: cinder-scheduler service_name: cinder-scheduler
init_config_overrides: "{{ cinder_scheduler_init_overrides }}" init_config_overrides: "{{ cinder_scheduler_init_overrides }}"
start_order: 2
cinder-volume: cinder-volume:
group: cinder_volume group: cinder_volume
service_name: cinder-volume service_name: cinder-volume
init_config_overrides: "{{ cinder_volume_init_overrides }}" init_config_overrides: "{{ cinder_volume_init_overrides }}"
start_order: 3
cinder-backup: cinder-backup:
group: cinder_backup group: cinder_backup
service_name: cinder-backup service_name: cinder-backup
condition: "{{ cinder_service_backup_program_enabled | bool }}" condition: "{{ cinder_service_backup_program_enabled | bool }}"
init_config_overrides: "{{ cinder_backup_init_overrides }}" init_config_overrides: "{{ cinder_backup_init_overrides }}"
start_order: 4
# This variable is used by the repo_build process to determine # This variable is used by the repo_build process to determine
# which host group to check for members of before building the # which host group to check for members of before building the

View File

@ -22,11 +22,11 @@
- name: Stop services - name: Stop services
service: service:
name: "{{ item.value.service_name }}" name: "{{ item.service_name }}"
enabled: yes enabled: yes
state: stopped state: stopped
daemon_reload: "{{ (ansible_service_mgr == 'systemd') | ternary('yes', omit) }}" daemon_reload: "{{ (ansible_service_mgr == 'systemd') | ternary('yes', omit) }}"
with_dict: "{{ filtered_cinder_services }}" with_items: "{{ filtered_cinder_services }}"
register: _stop register: _stop
until: _stop | success until: _stop | success
retries: 5 retries: 5
@ -51,11 +51,11 @@
- name: Start services - name: Start services
service: service:
name: "{{ item.value.service_name }}" name: "{{ item.service_name }}"
enabled: yes enabled: yes
state: "started" state: "started"
daemon_reload: "{{ (ansible_service_mgr == 'systemd') | ternary('yes', omit) }}" daemon_reload: "{{ (ansible_service_mgr == 'systemd') | ternary('yes', omit) }}"
with_dict: "{{ filtered_cinder_services }}" with_items: "{{ filtered_cinder_services }}"
register: _start register: _start
until: _start | success until: _start | success
retries: 5 retries: 5

View File

@ -16,51 +16,51 @@
- name: Create TEMP run dir - name: Create TEMP run dir
file: file:
path: "/var/run/{{ item.value.service_name }}" path: "/var/run/{{ item.service_name }}"
state: directory state: directory
owner: "{{ cinder_system_user_name }}" owner: "{{ cinder_system_user_name }}"
group: "{{ cinder_system_group_name }}" group: "{{ cinder_system_group_name }}"
mode: "02755" mode: "02755"
with_dict: "{{ filtered_cinder_services }}" with_items: "{{ filtered_cinder_services }}"
- name: Create TEMP lock dir - name: Create TEMP lock dir
file: file:
path: "/var/lock/{{ item.value.service_name }}" path: "/var/lock/{{ item.service_name }}"
state: directory state: directory
owner: "{{ cinder_system_user_name }}" owner: "{{ cinder_system_user_name }}"
group: "{{ cinder_system_group_name }}" group: "{{ cinder_system_group_name }}"
mode: "02755" mode: "02755"
with_dict: "{{ filtered_cinder_services }}" with_items: "{{ filtered_cinder_services }}"
# TODO(mgariepy): # TODO(mgariepy):
# Remove this in Pike as it only needed to handle upgrades # Remove this in Pike as it only needed to handle upgrades
# from Newton->Newton and Newton->Ocata # from Newton->Newton and Newton->Ocata
- name: Cleanup old tmpfiles.d entry - name: Cleanup old tmpfiles.d entry
file: file:
path: "/etc/tmpfiles.d/{{ item.value.service_name }}.conf" path: "/etc/tmpfiles.d/{{ item.service_name }}.conf"
state: absent state: absent
with_dict: "{{ filtered_cinder_services }}" with_items: "{{ filtered_cinder_services }}"
- name: Create tmpfiles.d entry - name: Create tmpfiles.d entry
template: template:
src: "cinder-systemd-tmpfiles.j2" src: "cinder-systemd-tmpfiles.j2"
dest: "/etc/tmpfiles.d/openstack-{{ item.value.service_name }}.conf" dest: "/etc/tmpfiles.d/openstack-{{ item.service_name }}.conf"
mode: "0644" mode: "0644"
owner: "root" owner: "root"
group: "root" group: "root"
with_dict: "{{ filtered_cinder_services }}" with_items: "{{ filtered_cinder_services }}"
notify: notify:
- Restart cinder services - Restart cinder services
- name: Place the systemd init script - name: Place the systemd init script
config_template: config_template:
src: "cinder-systemd-init.j2" src: "cinder-systemd-init.j2"
dest: "/etc/systemd/system/{{ item.value.service_name }}.service" dest: "/etc/systemd/system/{{ item.service_name }}.service"
mode: "0644" mode: "0644"
owner: "root" owner: "root"
group: "root" group: "root"
config_overrides: "{{ item.value.init_config_overrides }}" config_overrides: "{{ item.init_config_overrides }}"
config_type: "ini" config_type: "ini"
with_dict: "{{ filtered_cinder_services }}" with_items: "{{ filtered_cinder_services }}"
notify: notify:
- Restart cinder services - Restart cinder services

View File

@ -11,9 +11,9 @@ User={{ cinder_system_user_name }}
Group={{ cinder_system_group_name }} Group={{ cinder_system_group_name }}
{% if program_override is defined %} {% if program_override is defined %}
ExecStart={{ program_override }} {{ program_config_options|default('') }} --log-file=/var/log/cinder/{{ item.value.service_name }}.log ExecStart={{ program_override }} {{ program_config_options|default('') }} --log-file=/var/log/cinder/{{ item.service_name }}.log
{% else %} {% else %}
ExecStart={{ cinder_bin }}/{{ item.value.service_name }} {{ program_config_options|default('') }} --log-file=/var/log/cinder/{{ item.value.service_name }}.log ExecStart={{ cinder_bin }}/{{ item.service_name }} {{ program_config_options|default('') }} --log-file=/var/log/cinder/{{ item.service_name }}.log
{% endif %} {% endif %}
# Give a reasonable amount of time for the server to start up/shut down # Give a reasonable amount of time for the server to start up/shut down

View File

@ -1,5 +1,5 @@
# {{ ansible_managed }} # {{ ansible_managed }}
D /var/lock/{{ item.value.service_name }} 2755 {{ cinder_system_user_name }} {{ cinder_system_group_name }} D /var/lock/{{ item.service_name }} 2755 {{ cinder_system_user_name }} {{ cinder_system_group_name }}
D /var/run/{{ item.value.service_name }} 2755 {{ cinder_system_user_name }} {{ cinder_system_group_name }} D /var/run/{{ item.service_name }} 2755 {{ cinder_system_user_name }} {{ cinder_system_group_name }}
D {{ cinder_lock_path }} 2755 {{ cinder_system_user_name }} {{ cinder_system_group_name }} D {{ cinder_lock_path }} 2755 {{ cinder_system_user_name }} {{ cinder_system_group_name }}

View File

@ -34,13 +34,16 @@ cinder_package_list: |-
# #
# Compile a list of the services on a host based on whether # Compile a list of the services on a host based on whether
# the host is in the host group and the service is enabled. # the host is in the host group and the service is enabled.
# The service list is provided in the defined start order.
# #
filtered_cinder_services: > filtered_cinder_services: |-
{%- set services = cinder_services.copy() %} {% set services = [] %}
{%- for key,value in cinder_services.items() %} {% for key, value in cinder_services.items() %}
{%- if value.group not in group_names or {% if (value['group'] in group_names) and
(value.condition is defined and not value.condition) %} (('condition' not in value) or
{%- set _ = services.pop(key) %} ('condition' in value and value['condition'])) %}
{%- endif %} {% set _ = value.update({'service_key': key}) %}
{%- endfor %} {% set _ = services.append(value) %}
{{- services -}} {% endif %}
{% endfor %}
{{ services | sort(attribute='start_order') }}