Skip to content

feat: add opt-in inputs for a node pool Service - #71

Merged
scarmuega merged 1 commit into
mainfrom
feat/node-capacity-pool-inputs
Oct 1, 2026
Merged

scarmuega merged 1 commit into
mainfrom
feat/node-capacity-pool-inputs

Conversation

@scarmuega

Copy link
Copy Markdown
Member

Implements the demeter-run plan ogmios-improvement-node-capacity-node-module (decision 0029: one mainnet node pool on Spot, balanced through a headless Service). The bootstrap/ module gets four opt-in inputs. Wiring stage4 and choosing values is a separate change.

New inputs

Input Where Default Effect
termination_grace_period_seconds instances[*] null Rendered on the pod spec when set; null keeps the Kubernetes default (30 s). Validated as a positive whole number.
spread_hosts instances[*] false Adds a preferred pod anti-affinity: weight 100, kubernetes.io/hostname, selector role=node, network=<instance network>. It sits beside the existing node affinity, which is unchanged. It is never required, because the cluster has no autoscaler.
headless services[*] false cluster_ip = "None" and publish_not_ready_addresses = false, with the same selector and ports (n2c 3307, n2n 3000). _n2c._tcp.<name>.<namespace>.svc.cluster.local then lists Ready pods only.
pdb_max_unavailable services[*] null When set, a policy/v1 PodDisruptionBudget named after the Service, with this maxUnavailable and the Service's selector. Validated as a non-negative whole number.

The nodes-<salt> peer Services are untouched and still publish not-ready addresses for the mempool mesh.

Existing callers see no diff

  • With every input unset, the rendered values are the same as before. Grace is null (unset). The affinity block renders under the same condition as before. cluster_ip and publish_not_ready_addresses are null (unset). The PDB count is 0.
  • Checked against prod config: I ran a read-only terraform plan -refresh=false -lock=false -target=module.ext_cnode_m1 for m2-prod-7xjh33/stage4 twice, using the same state and config. The only difference between the runs was the module: once the pinned aade6e2, once this branch. Both plans have the same output, 0 to add, 4 to change, 0 to destroy. Those 4 changes are readiness-probe updates on the preprod/preview b00/b10 instances, committed in stage4 but not yet applied. This PR adds none of them.
  • instance/node.tf shows a large diff only because the existing node_affinity block is now a dynamic block, so spread_hosts can render without an empty node affinity. Review with git diff -w.

Note for wiring: switching an existing Service to headless changes its cluster IP, and Terraform will replace that Service. Add a new Service entry instead. The README says this too.

Verification (in bootstrap/)

  • terraform fmt -check: pass. (fmt -check -recursive still flags crds/main.tf, feature/config.tf and relay/main.tf. That drift was already on main and is left alone here.)
  • terraform validate: pass. The warnings are the existing provider deprecation notices.
  • terraform test: 20 passed, 0 failed. The new tests/node_capacity.tftest.hcl has 11 runs:
    • grace is rendered when set, left unset when not, and rejected at 0;
    • the anti-affinity is preferred-only with weight 100, hostname topology and a role/network selector, and leaves the node affinity as it was;
    • with neither input set, no affinity block is rendered;
    • a headless Service has cluster_ip = "None", publish_not_ready_addresses = false, the usual selector and both ports;
    • the PDB exists only when pdb_max_unavailable is set, takes the Service's name and selector, and carries the value;
    • the root passes all four inputs through.
  • I checked that the tests catch regressions: flipping publish_not_ready_addresses to true, or changing the weight to 50, fails the matching runs.

🤖 Generated with Claude Code

Per instance: termination_grace_period_seconds and spread_hosts (a
preferred hostname anti-affinity). Per Service: headless (Ready-only
DNS) and pdb_max_unavailable (a PodDisruptionBudget named after the
Service). All default off; existing callers render unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@scarmuega
scarmuega merged commit 3fe4e35 into main Oct 1, 2026
1 check failed
@scarmuega
scarmuega deleted the feat/node-capacity-pool-inputs branch October 1, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant