orchestrata_ultimate.promotion.unit_deps

Reference › orchestrata_ultimate › promotion › unit_deps

requires_bindsto_names returns every value of the Requires= and BindsTo= lines of a systemd unit file, split on whitespace. It is a port of the matching step in the target's install.sh; After= only orders startup and is not read. An unreadable file gives an empty list. Both stages_units (choosing the units to restart) and identity_skips (skipping units that cannot run on the host) use it, so the two agree on what "runnable here" means.

At a glance

Source src/orchestrata_ultimate/promotion/unit_deps.py
Lines of code 39
Classes 0
Functions 1
Imports (internal) none
Imported by orchestrata_ultimate.promotion.identity_skips, orchestrata_ultimate.promotion.stages, orchestrata_ultimate.promotion.stages_units
Tests that import it none

Class diagram

No classes; see Functions.

Dependency diagram

Dependency diagram orchestrata_ultimate.promotion.unit_deps

API

Functions

Function Signature Summary
requires_bindsto_names requires_bindsto_names(unit_file: Path) -> list[str] Every Requires=/BindsTo= value, space-split.

Source

Permalink: https://gitlab.com/MSamy/orchestrata-ultimate-architecture/-/blob/a4cbc2bdf/src/orchestrata_ultimate/promotion/unit_deps.py

"""Requires=/BindsTo= dependency-name parsing for promote's services stage.

``daemon_units`` (``stages.py``) mirrors ``deploy/systemd/install.sh``'s unit
filters so the promote's services stage skips exactly what ``install.sh``
would skip. ``install.sh`` (U-UNIT1) added a fourth filter this mirror lacked:
a unit whose ``Requires=``/``BindsTo=`` names a unit systemd cannot load is
not started. This module holds the small, pure piece of that filter --
extracting the dependency names -- split out because ``stages.py`` is already
1135 lines (over RUL-021's 300-line cap) before this addition. The actual
"is it loadable" check stays in ``daemon_units`` itself, reusing that
module's own ``_scope``/``_systemctl``/``_run`` helpers in place, which keeps
this module free of any import back on ``stages`` (avoiding a cycle).
"""

from __future__ import annotations

from pathlib import Path


def requires_bindsto_names(unit_file: Path) -> list[str]:
    """Every ``Requires=``/``BindsTo=`` value, space-split.

    Exactly install.sh's own ``awk -F'=' '/^(Requires|BindsTo)=/ { print
    $2 }'`` followed by bash's ``for dep in $(...)`` word-splitting, ported
    verbatim. ``After=`` only orders startup -- it is not a hard dependency
    and is not checked here, matching install.sh.
    """
    try:
        text = unit_file.read_text(encoding="utf-8")
    except OSError:
        return []
    names: list[str] = []
    for line in text.splitlines():
        key, sep, value = line.partition("=")
        if not sep:
            continue
        if key.strip() in ("Requires", "BindsTo"):
            names.extend(value.split())
    return names