Skip to content

Fix timezone.zone_compare when /etc/localtime is missing on Debian (3006.x)#69809

Open
dwoz wants to merge 1 commit into
saltstack:3006.xfrom
dwoz:fix/69803-zone-compare-missing-localtime
Open

Fix timezone.zone_compare when /etc/localtime is missing on Debian (3006.x)#69809
dwoz wants to merge 1 commit into
saltstack:3006.xfrom
dwoz:fix/69803-zone-compare-missing-localtime

Conversation

@dwoz

@dwoz dwoz commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Backports the fix for timezone.zone_compare when /etc/localtime is missing (originally shipped in 3007.x / 3008.x / master via commit 8cc89835b41 for #65719) to the 3006.x LTS branch.

What is the current bug behavior?

On systemd-managed hosts such as Debian 12 arm64, /etc/localtime may be absent while timedatectl still reports a valid timezone. On 3006.x, timezone.zone_compare only bypasses the filecmp-based check for the Arch and FreeBSD families. Every other systemd distro (Debian, RedHat/Alma/Rocky, ...) falls through to filecmp.cmp(/etc/localtime, ...) which raises:

salt.exceptions.CommandExecutionError:
Failed to read /etc/localtime to determine current timezone: No such file or directory

The state module surfaces this as:

Unable to compare desired timezone 'Europe/Zurich' to system timezone:
Failed to read /etc/localtime to determine current timezone: No such file or directory

What is the new behavior?

zone_compare now tries get_zone() first (which uses timedatectl when available) and only falls back to the filecmp-based comparison if get_zone cannot determine the running zone. get_zone's os_family branching is simplified to match newer branches, and _timedatectl is invoked with the same cmd.run_all call signature as 3007.x+ so the unit-test surface matches.

Reproduction

On a Debian 12 minion:

sudo rm -f /etc/localtime
timedatectl show -p Timezone --value   # still prints Europe/Zurich
sudo salt-call state.sls timezone pillar='{"timezone":"Europe/Zurich"}'

Before this PR: state fails with the error above.
After this PR: state succeeds because the timedatectl-reported zone is trusted.

Tests

  • New regression test test_zone_compare_missing_localtime_with_timedatectl covers the Debian + missing localtime + timedatectl-reported zone path. Verified it fails against pre-fix 3006.x code and passes with the fix.
  • Full tests/pytests/unit/modules/test_timezone.py (33 tests) passes.

Related

Merge requirements

  • Bug fix
  • Test coverage
  • Changelog entry

Backport of the 3007.x/3008.x/master fix (originally saltstack#65719) to 3006.x.

On systemd-managed hosts such as Debian 12 arm64, /etc/localtime may be
absent while ``timedatectl`` still reports a valid timezone. Prior to
this change, ``timezone.zone_compare`` on 3006.x only bypassed the
``filecmp`` check for Arch and FreeBSD. On Debian it raised
``CommandExecutionError`` from ``filecmp.cmp`` and made the
``timezone.system`` state fail with::

    Unable to compare desired timezone 'Europe/Zurich' to system
    timezone: Failed to read /etc/localtime to determine current
    timezone: No such file or directory

Restructure ``zone_compare`` to trust ``get_zone`` first (which uses
``timedatectl`` when available) and only fall back to the
``filecmp``-based comparison if ``get_zone`` cannot determine the zone.
Also simplify ``get_zone``'s os_family branching and use the same
``cmd.run_all`` invocation as newer branches so the unit-test surface
matches.

Fixes saltstack#69803
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:full Run the full test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants