Skip to content

Topology: YAML topology files and gateway priorities - #679

Open
thiell wants to merge 4 commits into
clustershell:masterfrom
thiell:feature/gh374-topology-yaml
Open

Topology: YAML topology files and gateway priorities#679
thiell wants to merge 4 commits into
clustershell:masterfrom
thiell:feature/gh374-topology-yaml

Conversation

@thiell

@thiell thiell commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Implements the design discussed in #374 (see the design comment). Closes #374.

YAML topology files

  • New topology.yaml file syntax: routes as a list of gateways/targets objects. Selected by file extension (.yaml/.yml), so --topology works with both syntaxes; INI topology.conf remains fully supported.
  • Unlike INI, the same gateways may appear in several routes: one gateway pool can reach several target groups, with symmetric failback — the core need from the PR Tree: support optional route weights in topology.conf (#374) #678 review.
  • topology.yaml is preferred over topology.conf when both exist at the same config location.
  • TopologyParser becomes a thin facade over per-format backends; graph building and validation are unchanged and format-agnostic. The INI code path is untouched and still covered by the existing tests.
  • PyYAML stays an optional lazy import, only when a YAML topology is loaded (same pattern as YAML group files). pip, Fedora/EPEL and Debian packages already require it; without it, only .yaml topologies fail.

Gateway priorities

  • In YAML, the gateways of a route may be a list of entries with descriptive attributes, in the style of modern YAML tools such as lnetctl: nodes (node set, required), weight (load share among gateways of equal priority, default 1) and priority (failover rank, default 1). A lower number means a higher priority: gateways of a given priority are used only when all gateways with a lower priority number are unreachable:
routes:
  - gateways:
      - nodes: gw1
      - nodes: gw2
        priority: 2         # gw1 default, gw2 failover
    targets:  rio[100-199]
  - gateways:
      - nodes: gw2
      - nodes: gw1
        priority: 2         # gw2 default, gw1 failover
    targets:  rio[200-299]
  • A plain list of node sets (gateways: [gw1, gw2]) is a load-shared pool, equivalent to gateways: gw[1-2] — failover is always explicit with priority, and the entry form keeps the schema extensible for future per-gateway attributes.
  • Gateways of equal priority share the load with least-connections as today, weighted by weight (integers >= 1). Weight 0 is rejected: a standby gateway is a higher priority number, so there is only one mechanism.
  • Priorities apply to all traffic routed through the pool, including targets deeper in the tree.
  • Routes may not have overlapping targets, and a gateway may not appear twice in one gateways list with different weights or priorities: both are rejected at parse time.
  • Resolved priorities ride the pickled TopologyTree; trees from older versions are still accepted, and the wire protocol is unchanged.

Error reporting

  • YAML errors name the route and the accepted keys: topology.yaml: route #3: unsupported gateway entry key(s): prio (expected: nodes, priority, weight).
  • A topology.conf holding YAML syntax now says so, instead of just Invalid configuration file. INI parsing itself is unchanged.

Docs and tests

  • config.rst/clush.rst document the YAML syntax, quoting rules (@group values must be quoted), precedence and priorities — including explicitly that a lower priority number wins; conf/topology.yaml.example added.
  • New tests/TreeRouterTest.py covers gateway selection: priority order, failover, mutual failback, weighted distribution, pool equivalence of plain lists, multi-level trees, pickled-tree round-trip, pre-1.11 tree compatibility. YAML parser tests added to TreeTopologyTest, including INI/YAML tree equivalence.

Supersedes PR #678 (now a draft): the INI [weights] section is not kept, and its weighted least-connections selection is reused as the load-sharing policy among gateways of equal priority.

Turn TopologyParser into a thin facade over an internal ConfigParser
and an intermediate route list, so that a second configuration format
can be added. No behavior change.

Signed-off-by: Stephane Thiell <stephane@thiell.com>
@thiell thiell added this to the 1.11 milestone Jul 18, 2026
@thiell
thiell requested review from degremont and kcgthb July 19, 2026 00:00
@thiell
thiell force-pushed the feature/gh374-topology-yaml branch from feacb1d to 63b60a9 Compare July 19, 2026 15:27
@thiell
thiell force-pushed the feature/gh374-topology-yaml branch from 63b60a9 to a2755a8 Compare July 24, 2026 03:03
@thiell thiell changed the title Topology: YAML topology files and ordered gateway tiers Topology: YAML topology files and gateway priorities Jul 24, 2026
@thiell

thiell commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator Author

Renamed tier to priority as agreed in #374; docs now state explicitly that a lower number means a higher priority.

@thiell thiell self-assigned this Jul 24, 2026
@degremont

Copy link
Copy Markdown
Collaborator

Thanks for the patch.
Overall good, but some ambiguity if in the config file, gateways or target nodes overlap.
By example, the following config is allowed, but routing for node5 is unclear:

routes:
- gateways: admin
  targets: gw[1-2]

# gw1 preferred
- gateways:
  - nodes: gw1
  - nodes: gw2
    priority: 2
  targets: node[0-9]

# gw2 preferred
- gateways:
  - nodes: gw2
  - nodes: gw1
    priority: 2
  targets: node[5-14]
  • When targets overlap, and gateways are common, we should not allow that. (fine if this is totally different gateways)

Similarly, we should avoid:

gateways:
- nodes: gw[1-2]
- nodes: gw2
  priority: 2

Minor: we should tell to AI to not add ticket ID or PR ID in code comment, unless we will eventually have this kind of ref every where in the code. git blame can always tell. Exception if this is a very tricky piece of code, and details/explanation are needed, and reference to a ticket can help. But when this is just a new feature, I do not care about the original ticket ID.

@thiell
thiell force-pushed the feature/gh374-topology-yaml branch from a2755a8 to cd14600 Compare July 27, 2026 03:43
@thiell

thiell commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks, both confirmed and fixed.

  • Overlapping targets with common gateways — worse than your example: all of node[0-14] follow whichever route is listed first, so even node[10-14] lose the preference they declared. Also covers the same-targets/contradictory-priorities variant.
TopologyError: Overlapping targets detected (node[5-9])! Cannot add route gw[1-2] -> node[5-14]
  • Duplicate gateway in a gateways: list — reads as "gw1 default, gw2 failover" but actually load-shares round-robin. Same check for a repeat at equal priority with a different weight.
TopologyError: Duplicate gateway (gw2) in the gateways of gw[1-2]
  • Overlapping targets with totally different gateways was already rejected, since 2011 — left as is:
TopologyError: Convergent path detected! Cannot add route gw[3-4] -> node[5-14]
  • The rule lives in the graph layer, so INI is tightened too when one file spells the same pool two ways (gw[1-2]: and gw1,gw2:) with overlapping targets.
  • Ticket IDs dropped from the code comments; kept the two GH#527 (bug-workaround refs).

@degremont degremont left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thiell
thiell force-pushed the feature/gh374-topology-yaml branch from cd14600 to 2cc637a Compare July 28, 2026 02:06
@thiell

thiell commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator Author
  • schema errors name the route + accepted keys: topology.yaml: route #3: unsupported gateway entry key(s): prio (expected: nodes, priority, weight)
  • YAML in a .conf now points to the .yaml extension (expected common user error)
  • new tests: duplicate keys, anchors/merge keys, no section header; also checked on py2.7 + PyYAML 3.10
  • Also dropped the PyYAML question from the description — optional lazy import, packages all require it already.

@thiell
thiell requested a review from degremont July 28, 2026 02:13
thiell added 3 commits July 27, 2026 19:53
Add a YAML topology file syntax, selected by .yaml/.yml file
extension. Routes are a list of gateways/targets objects and the
same gateways may appear in several routes. topology.yaml is
preferred over topology.conf at each config location. INI stays
fully supported. PyYAML is imported lazily, as for YAML group files.

Signed-off-by: Stephane Thiell <stephane@thiell.com>
In a YAML topology file, the gateways of a route may be a list of
entries with nodes, weight and priority attributes. A lower number
means a higher priority: gateways of a given priority are used only
when all gateways with a lower priority number are unreachable.
Gateways of equal priority share the load using weighted
least-connections. Resolved priorities ride the propagation tree
sent to gateways; older trees without priorities are still accepted.

Signed-off-by: Stephane Thiell <stephane@thiell.com>
Document the topology.yaml syntax, gateway priorities and discovery
precedence in config.rst and clush.rst. INI topology.conf remains
documented as fully supported.

Signed-off-by: Stephane Thiell <stephane@thiell.com>
@thiell
thiell force-pushed the feature/gh374-topology-yaml branch from 2cc637a to 2a13f55 Compare July 28, 2026 03:01
@thiell

thiell commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator Author

I briefly had a strict SafeLoader rejecting duplicate YAML keys (PyYAML keeps the last value silently) but dropped it: cluster.yaml group files tolerate the same thing, so it would have been inconsistent.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gateway: add hop/weight parameter to routes

2 participants