Skip to content

util

_util

Re-exports the executor-only timezone helper.

Standalone — no terok-executor domain imports, safe to use from any layer. Cross-package helpers (ensure_dir, podman_userns_args, the round-trip YAML facade in terok_util.yaml, ...) live in the shared terok_util package and are imported from there directly.

__all__ = ['detect_host_timezone'] module-attribute

detect_host_timezone()

Return the host's IANA timezone name, or None if it can't be detected.

Tried in order:

  1. $TZ — the user's explicit override.
  2. /etc/timezone — Debian/Ubuntu convention, single-line zone name.
  3. /etc/localtime symlink — systemd-family hosts (and macOS) symlink this into the zoneinfo database; the zone name is the path suffix after the zoneinfo/ component.

Returns None on hosts that expose none of the above (containers with only a copied-in /etc/localtime file, for instance), letting the caller fall back to the image default rather than guessing.

Source code in src/terok_executor/_util/_timezone.py
def detect_host_timezone() -> str | None:
    """Return the host's IANA timezone name, or ``None`` if it can't be detected.

    Tried in order:

    1. ``$TZ`` — the user's explicit override.
    2. ``/etc/timezone`` — Debian/Ubuntu convention, single-line zone name.
    3. ``/etc/localtime`` symlink — systemd-family hosts (and macOS) symlink
       this into the zoneinfo database; the zone name is the path suffix
       after the ``zoneinfo/`` component.

    Returns ``None`` on hosts that expose none of the above (containers with
    only a copied-in ``/etc/localtime`` file, for instance), letting the
    caller fall back to the image default rather than guessing.
    """
    if tz := os.environ.get("TZ"):
        return tz

    try:
        if zone := Path("/etc/timezone").read_text(encoding="utf-8").strip():
            return zone
    except OSError:
        pass

    try:
        target = Path("/etc/localtime").resolve().as_posix()
    except OSError:
        return None
    if _ZONEINFO_MARKER in target:
        return target.split(_ZONEINFO_MARKER, 1)[1]
    return None