Relocates `cli/meta/{ports,networks/suggest}` to
`cli/contributing/network/{ports,address/suggest}` so port and subnet
allocators live alongside the rest of the contributor-side tooling
(mirror, update, changelog) instead of `meta`. Mirrors the tests
into `tests/unit/cli/contributing/network/` and renames the contract
docs to `docs/contributing/tools/network/{port,address}.md`. Prog
names update from `cli meta ports suggest` / `cli meta networks
suggest` to `cli contributing network ports suggest` / `cli
contributing network address suggest`; the corresponding lint
references and `utils.meta.scan` docstring follow.
Adds a third subcommand: `cli contributing network diagnose`
(stdlib-only DNS / TCP / TLS / PMTU probe against the standard
infrastructure hosts plus interface MTU, `/etc/resolv.conf`,
`/etc/hosts`, proxy env, CA-bundle summaries). Split across `cli.py`
(orchestration), `config.py` (SPOT for hosts / per-distro install
commands), `format.py` (output + subprocess helpers), `tools.py`
(distro-aware auto-install of `iputils-ping` + `iproute2`),
`report.py` (system-info dumps + IPv6-default-route detection), and
`probes.py` (per-host probes). Exposed as `make debug-network`.
Companion `docs/contributing/actions/debugging/network.md` absorbs
the diagnose-tool walkthrough (incl. how to read MTU-induced TLS
handshake timeouts) so the merged page covers DNS / MTU / IPv6 /
connectivity end-to-end.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.9 KiB
cli contributing network ports suggest 🚪
This page documents the contract of the cli contributing network ports suggest helper and the rules contributors MUST follow when calling it.
Primary file:
Purpose 🎯
cli contributing network ports suggest proposes the next free host-bound port(s) inside a PORT_BANDS.<scope>.<category> band defined in group_vars/all/08_networks.yml.
It walks every roles/*/meta/services.yml, collects occupied <entity>.ports.{local,public}.<category> assignments across all roles and all entities, and proposes free slots gap-first then by increment.
internal ports are NOT supported by the suggester; they are dictated by upstream container images (gitea=3000, postgres=5432, …) and not allocated from a project-managed pool.
Internal ports are recorded in services.<entity>.ports.internal.<category> directly by the contributor.
Inputs 🔧
| Flag | Required | Default | Description |
|---|---|---|---|
--scope local|public |
yes | n/a | Which scope to allocate from. internal is NOT a supported value. |
--category <name> |
yes | n/a | Band category (http, ssh, oauth2, relay, …). Looked up in PORT_BANDS.<scope>.<category>. |
--count N |
no | 1 |
How many free ports (or relay ranges) to return. |
--range <start>-<end> |
no | n/a | Override the band from PORT_BANDS for ad-hoc allocations. |
--length N |
yes for relay |
n/a | Inclusive port count of the contiguous range. The produced span is {start, end = start + N - 1}. |
Behaviour 🧮
Single-port categories (everything except relay)
- Read the band for
<scope>.<category>fromPORT_BANDS. If absent and no--rangeis given, exit non-zero with a clear error listing the available categories. - Walk every
roles/*/meta/services.ymland collect ints under<entity>.ports.<scope>.<category>(across ALL entities and ALL roles). - Gap-first: propose the lowest unoccupied port in the band.
- Increment fallback: if the band has no internal gaps, propose
max(used) + 1(clamped to the band's upper bound). - Exit non-zero if the requested count cannot be satisfied within the band.
Range category relay
- Read the relay band from
PORT_BANDS.public.relay. - Collect every
<entity>.ports.public.relay.{start,end}pair as an occupied span. - Gap-first: propose the lowest unoccupied contiguous span of size
--length Nwithin the band. - Increment fallback: if no internal gap fits, propose
max(end) + 1tomax(end) + N(clamped to the band's upper bound). - Exit non-zero if
Kranges of sizeNcannot be fit within the band.
Output 📤
- stdout prints a machine-readable list (one port per line for single-port categories, one
<start>-<end>pair per line forrelay). - stderr prints a human-readable summary noting which band was used and how many gaps were filled vs. appended.
Examples 💡
Suggest three free localhost HTTP ports inside PORT_BANDS.local.http:
cli contributing network ports suggest --scope local --category http --count 3
Suggest one free public SSH port (PORT_BANDS.public.ssh):
cli contributing network ports suggest --scope public --category ssh --count 1
Suggest one free 10 000-port public relay range (PORT_BANDS.public.relay):
cli contributing network ports suggest --scope public --category relay --length 10000
Suggest five free oauth2-callback ports inside an explicit ad-hoc range:
cli contributing network ports suggest --scope local --category oauth2 --count 5 \
--range 16500-16599
Determinism 🧪
Given the same on-disk role layout and the same arguments, the helper produces identical output. It exits non-zero with a clear error when the requested capacity cannot be satisfied within the configured band.
Integration with cli create role 🧩
When cli create role scaffolds a new role, it prompts for required port categories per service entity and calls cli contributing network ports suggest --scope <…> --category <…> --count 1 per slot to fill in the entity's ports map.
The contributor MAY override either suggestion interactively.
See address.md for the matching subnet flow.
Related Pages 📚
- address.md is the sibling helper for subnets.
- layout.md describes the per-entity
portsshape.