Skip to content

The clock assert never runs, so fail_msg never renders #212

Description

@t0kubetsu

Summary

The assert task that checks the clock never runs, so fail_msg never renders. The operator sees a raw retry failure with no explanation of the cause.

This issue follows #208. In #208, @hyde-repo classified this defect as a bug.

Separately, the dead assert and the Fedora path do qualify as bugs. Please open a dedicated issue for them and feel free to propose the fix.

Scope, as agreed in #208: the fix stays inside the existing tasks, with no restructuring.

Severity: MEDIUM. The defect hides the reason for the failure. The defect does not change whether the deployment fails.

The Fedora faults of the same role are #213. The two issues are independent, and this one needs no decision.

Location

The defect exists in the copy that runs as of 2026-08-27:

Distribution File and lines
Ubuntu 02_ansible_layer/admin/roles/software.install.warmup.basic_packages/tasks/include/network/ntp_client/ubuntu/systemd_timesyncd.yaml:61-75
Fedora 02_ansible_layer/admin/roles/software.install.warmup.basic_packages/tasks/include/network/ntp_client/fedora/systemd_timesyncd.yaml:56-69

The defect also exists in both copies inside service.reload.ntp, which no scenario includes. #208 carries the question of which copy is authoritative.

The block below is abridged. The block is dedented, and it omits the success_msg and comment lines.

- name: wait time drift - ubuntu
  command: timedatectl show -p NTPSynchronized --value
  register: ntp_sync_check
  until: ntp_sync_check.stdout == "yes"
  retries: 10
  delay: 5
  changed_when: false

- name: assert - time is sync - ubuntu
  assert:
    that:
      - ntp_sync_check.stdout == "yes"
    fail_msg: " clock is not sync!"

Mechanism

When the retries exhaust, the command task fails and aborts the block. The assert task never runs, so fail_msg never renders.

Current output for the operator:

fatal: [r42.admin-all-services-lab]: FAILED! => cmd: timedatectl show -p NTPSynchronized --value, stdout: "no", attempts: 10

Expected output: the text of fail_msg, which names the clock as the cause.

Fix

Add failed_when: false to the retry task, so the assert becomes the failing task.

Verified on ansible-core 2.20.2, with a local reproduction of the three cases:

Retry task Retry loop Task result assert fail_msg
current code exhausts fatal never runs not rendered
failed_when: false exhausts ok runs rendered
ignore_errors: true exhausts fatal, then ignored runs rendered, with the raw failure

Not verified on the pinned ansible-core 2.19.1. failed_when: false is the cleaner of the two working options, because ignore_errors still prints the raw retry failure.

The same construct in the bootstrapper

The same construct waits in a commented copy in the bootstrapper repository, at range42/roles/deployer.bootstrap/tasks/00_ntp.yml:39-58. Both tasks are commented there, so nothing is unreachable today. #208 proposes to re-enable that copy. Re-enabling it as written would reproduce this defect.

Reproduction

Run the role on an Ubuntu guest, on a segment where UDP port 123 is filtered. The retry loop exhausts, and the operator sees stdout: "no" with no fail_msg.

Acceptance criteria

#208 leaves the meaning of "with tests" open. These criteria assume acceptance at the playbook level, as proposed in #208.

  • A forced failure of the time check renders fail_msg, instead of a bare stdout: "no".
  • The retry loop still runs its 10 attempts before the assert fails.
  • A deployment on a segment with working NTP egress still succeeds.
  • Both copies of the task files carry the fix, or only one copy remains in the repository.

Out of scope

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugtrack_axis-00Core stabilisation and hardening

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions