diff --git a/ansible/chrony-cleanup.yml b/ansible/chrony-cleanup.yml new file mode 100644 index 0000000000..1742a1207f --- /dev/null +++ b/ansible/chrony-cleanup.yml @@ -0,0 +1,14 @@ +--- +- name: Remove chrony container + gather_facts: false + hosts: + - chrony-server + - chrony + serial: '{{ kolla_serial|default("0") }}' + tags: + - chrony + tasks: + - import_role: + name: chrony + tasks_from: cleanup.yml + when: not enable_chrony | bool diff --git a/ansible/roles/chrony/tasks/cleanup.yml b/ansible/roles/chrony/tasks/cleanup.yml new file mode 100644 index 0000000000..79ef11602a --- /dev/null +++ b/ansible/roles/chrony/tasks/cleanup.yml @@ -0,0 +1,12 @@ +--- +- name: Stop and remove chrony container + become: true + kolla_docker: + action: "stop_and_remove_container" + name: chrony + +- name: Remove config for chrony + become: true + file: + path: "{{ node_config_directory }}/chrony" + state: "absent" diff --git a/ansible/roles/prechecks/defaults/main.yml b/ansible/roles/prechecks/defaults/main.yml index 6361801c83..f05d1116c5 100644 --- a/ansible/roles/prechecks/defaults/main.yml +++ b/ansible/roles/prechecks/defaults/main.yml @@ -1,3 +1,6 @@ --- # Whether to enable checks for host OS distribution and release. prechecks_enable_host_os_checks: true + +# Whether to enable checks for a host NTP daemon. +prechecks_enable_host_ntp_checks: true diff --git a/ansible/roles/prechecks/tasks/timesync_checks.yml b/ansible/roles/prechecks/tasks/timesync_checks.yml index fdbda89c71..8e4a7a844d 100644 --- a/ansible/roles/prechecks/tasks/timesync_checks.yml +++ b/ansible/roles/prechecks/tasks/timesync_checks.yml @@ -1,14 +1,71 @@ --- -- name: Checking timedatectl status +# TODO(mgoddard): Remove this check in the Y cycle after chrony has been +# dropped for a cycle. +- name: Get container facts become: true - command: timedatectl status - register: timedatectl_status - changed_when: false + kolla_container_facts: + name: + - chrony + register: container_facts -- name: Fail if the clock is not synchronized +- name: Fail if chrony container is running fail: msg: >- - timedatectl sees the system clock as unsynchronized. - Please wait for synchronization. + A chrony container is running, but 'enable_chrony' is 'false'. The chrony + container is deprecated from the Wallaby release, and the default value + of 'enable_chrony' was changed to 'false'. + + The chrony container may be cleaned up via 'kolla-ansible + chrony-cleanup'. You should then install and configure a suitable host + NTP daemon before running these prechecks again. + + To continue running the chrony container, set 'enable_chrony' to 'true', + however note that this feature will be removed in the Xena release, so it + is not recommended for use. when: - - "'synchronized: yes' not in timedatectl_status.stdout" + - "'chrony' in container_facts" + +- block: + - name: Check for a running host NTP daemon # noqa command-instead-of-module + vars: + prechecks_host_ntp_daemons: + - chrony + - chronyd + - ntp + - ntpd + - systemd-timesyncd + become: true + command: + cmd: "systemctl is-active {{ prechecks_host_ntp_daemons | join(' ') }}" + register: systemctl_is_active + changed_when: false + failed_when: false + + - name: Fail if a host NTP daemon is not running + fail: + msg: >- + No host NTP daemon is running, and the Kolla Ansible chrony container + is disabled. Please install and configure a host NTP daemon. + Alternatively, set 'prechecks_enable_host_ntp_checks' to 'false' to + disable this check if not using one of the following NTP daemons: + chrony, ntpd, systemd-timesyncd. + when: + - systemctl_is_active.rc != 0 + + - name: Checking timedatectl status + become: true + command: timedatectl status + register: timedatectl_status + changed_when: false + + - name: Fail if the clock is not synchronized + fail: + msg: >- + timedatectl sees the system clock as unsynchronized. + Please wait for synchronization. + Alternatively, set 'prechecks_enable_host_ntp_checks' to 'false' to + disable this check if your NTP daemon is not recognised by + 'timedatectl status'. + when: + - "'synchronized: yes' not in timedatectl_status.stdout" + when: prechecks_enable_host_ntp_checks | bool diff --git a/releasenotes/notes/deprecate-chrony-077a8686e79a919e.yaml b/releasenotes/notes/deprecate-chrony-077a8686e79a919e.yaml index ee8403a946..a0913640f7 100644 --- a/releasenotes/notes/deprecate-chrony-077a8686e79a919e.yaml +++ b/releasenotes/notes/deprecate-chrony-077a8686e79a919e.yaml @@ -2,8 +2,18 @@ deprecations: - | Support for deploying ``chrony`` is deprecated and will be removed in the - Xena cycle. - + Xena cycle. The container is no longer enabled by default. To enable it, + set ``enable_chrony`` to ``true``. upgrade: - | - Due to deprecation, ``chrony`` is no longer enabled by default. + Due to deprecation, ``chrony`` is no longer enabled by default. To enable + it, set ``enable_chrony`` to ``true``. + + If disabled, the container and configuration may be removed by running + ``kolla-ansible chrony-cleanup``. + + The ``kolla-ansible prechecks`` command will fail if Chrony is disabled and + the container is running. It will also fail if Chrony is disabled and no + host NTP daemon is detected. This check may be disabled by setting + ``prechecks_enable_host_ntp_checks`` to ``false`` if using an NTP daemon + other than chrony, ntpd or systemd-timesyncd. diff --git a/tests/pre.yml b/tests/pre.yml index 0a6a9f7eb8..c2f1d2e1a0 100644 --- a/tests/pre.yml +++ b/tests/pre.yml @@ -104,3 +104,31 @@ until: "'synchronized: yes' in timedatectl_status.stdout" retries: 90 delay: 10 + + # TODO(mgoddard): Remove this task in the Y cycle after chrony has been + # dropped for a cycle. + # NOTE(mgoddard): For upgrades, test the case where we are running + # a chrony container, but keep the default of disabled after the + # upgrade. + - block: + - name: Remove host NTP packages + become: true + package: + name: + - chrony + - ntp + state: absent + + # NOTE(mgoddard): removing the systemd-timesyncd package fails, so stop + # and disable it instead. + - name: Stop systemd-timesyncd service + become: true + service: + name: systemd-timesyncd + enabled: no + state: stopped + when: ansible_os_family == 'Debian' + when: + - is_upgrade + # cephadm gets grumpy without a host-level chrony. + - scenario != 'cephadm' diff --git a/tests/templates/globals-default.j2 b/tests/templates/globals-default.j2 index 65d5c71f7e..d9f4298071 100644 --- a/tests/templates/globals-default.j2 +++ b/tests/templates/globals-default.j2 @@ -33,12 +33,6 @@ enable_openstack_core: "{{ openstack_core_enabled }}" enable_horizon: "{{ dashboard_enabled }}" enable_heat: "{{ openstack_core_tested }}" -# TODO(yoctozepto): Remove this in the Xena cycle. -# We have to keep it for now for upgrades because dropping chronyd inbetween -# will make prechecks fail due to lack of proper host-level timesync (chronyd -# is containerized and the host-level client either removed or fought with). -enable_chrony: "no" - {% if scenario != 'bifrost' %} kolla_internal_vip_address: "{{ kolla_internal_vip_address }}" neutron_external_interface: "{{ neutron_external_interface_name }}" @@ -128,6 +122,10 @@ glance_backend_ceph: "yes" cinder_backend_ceph: "yes" nova_backend_ceph: "yes" ceph_nova_user: "cinder" + +# TODO(yoctozepto): Remove this in the Xena cycle. +# cephadm doesn't support chrony in a container (checks for chrony.service) +enable_chrony: "no" {% endif %} {% if tls_enabled %} diff --git a/tests/upgrade.sh b/tests/upgrade.sh index 39b6e8333d..26a198d9fc 100755 --- a/tests/upgrade.sh +++ b/tests/upgrade.sh @@ -13,6 +13,20 @@ function upgrade { if [[ "$TLS_ENABLED" = "True" ]]; then kolla-ansible -i ${RAW_INVENTORY} -vvv certificates > /tmp/logs/ansible/certificates fi + + # TODO(mgoddard): Remove this block in the Y cycle after chrony has been + # dropped for a cycle. + # NOTE(mgoddard): Remove the chrony container and install a host chrony + # daemon. + kolla-ansible -i ${RAW_INVENTORY} -vvv chrony-cleanup &> /tmp/logs/ansible/chrony-cleanup + if [[ $(source /etc/os-release && echo $ID) = "centos" ]]; then + chrony_service="chronyd" + else + chrony_service="chrony" + fi + ansible all -i $RAW_INVENTORY -m package -a 'name=chrony state=present' -b &> /tmp/logs/ansible/chrony-install + ansible all -i $RAW_INVENTORY -m service -a 'name='$chrony_service' state=started enabled=yes' -b &>> /tmp/logs/ansible/chrony-install + kolla-ansible -i ${RAW_INVENTORY} -vvv prechecks &> /tmp/logs/ansible/upgrade-prechecks kolla-ansible -i ${RAW_INVENTORY} -vvv pull &> /tmp/logs/ansible/pull-upgrade kolla-ansible -i ${RAW_INVENTORY} -vvv upgrade &> /tmp/logs/ansible/upgrade diff --git a/tools/kolla-ansible b/tools/kolla-ansible index 215bcf0ee4..be9c474707 100755 --- a/tools/kolla-ansible +++ b/tools/kolla-ansible @@ -152,6 +152,7 @@ Commands: upgrade-bifrost Upgrades an existing bifrost container genconfig Generate configuration files for enabled OpenStack services prune-images Prune orphaned Kolla images + chrony-cleanup Clean up disabled chrony containers EOF } @@ -466,6 +467,10 @@ EOF exit 1 fi ;; +(chrony-cleanup) + ACTION="Cleanup disabled chrony containers" + PLAYBOOK="${BASEDIR}/ansible/chrony-cleanup.yml" + ;; (bash-completion) bash_completion exit 0