Skip to content

fix: stop salt-api FD exhaustion + drive masters badge from config#705

Merged
hellodk merged 4 commits into
masterfrom
2026-06-21-hqr3
Jun 21, 2026
Merged

fix: stop salt-api FD exhaustion + drive masters badge from config#705
hellodk merged 4 commits into
masterfrom
2026-06-21-hqr3

Conversation

@hellodk

@hellodk hellodk commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • Root cause fix: salt-api on macOS inherits launchd's 256 soft open-file limit. Its cheroot server churns TLS connections + internal salt FDs and exhausts 256, after which accept() fails with [Errno 24] Too many open files — every /login and /run then returns HTTP 500, and new TLS handshakes drop as UNEXPECTED_EOF_WHILE_READING. Masters flip to unreachable on the dashboard. Added SoftResourceLimits/HardResourceLimits NumberOfFiles (salt_api_max_open_files=10240, configurable) to the salt-api launchd plist.
  • De-hardcode the health badge: SaltMasterStatus now reads the configured SaltMaster row (its api_url is derived server-side from address + salt_api_port + use_tls) and shows the backend-computed health, instead of probing a literal port 4507 against a non-existent /settings/probe endpoint.

Why this came up

Diagnosed live on the mm master (192.168.1.64): salt-api log showed OSError: [Errno 24] Too many open files. Restarting cleared it; raising the FD limit makes it durable. After the fix the probe reports healthy (all checks pass, 1 minion up).

Notes

  • The live daemon on 192.168.1.64 has already been patched + reloaded (maxfiles soft/hard = 10240); this PR makes the same change reproducible via the role for any re-provision.
  • Pre-existing masters still store port 8080 (migration bug: version number missing next to kri logo after deployment #51 intentionally did not rewrite existing rows). Migrating this host to 4507 is a separate operational step.

Test plan

  • Frontend builds (tsc + eslint pass in pre-commit).
  • Re-provision a macOS salt-master and confirm launchctl procinfo <pid> shows maxfiles => 10240.
  • Salt Masters tab shows the default master's real health, no hardcoded-port probe.

Made with Cursor

hellodk and others added 3 commits June 21, 2026 22:00
Changed the SALT_API_URL in multiple playbooks and documentation to reflect the new default port 4507 instead of 8080. This includes updates in install_salt_master.yml, install_salt_master_linux.yml, deploy_salt_master_mm1.yml, and the README.md for the salt_master role. Ensures consistency in configuration and avoids port collisions.
…d added new communities. Updated report to reflect changes in node and edge counts, and adjusted the date to 2026-06-21.
salt-api on macOS inherits launchd's 256 soft open-file limit, which its
cheroot server exhausts under TLS connection churn — accept() then fails with
[Errno 24] Too many open files, so every /login and /run returns HTTP 500 and
new TLS handshakes drop as UNEXPECTED_EOF, flipping masters to "unreachable"
on the dashboard. Add SoftResourceLimits/HardResourceLimits NumberOfFiles
(salt_api_max_open_files=10240) to the salt-api launchd plist so the service
stays serviceable.

Also rewrite SaltMasterStatus to read the configured SaltMaster row — whose
api_url is derived server-side from address + salt_api_port + use_tls — and
show the backend-computed health, instead of probing a hardcoded port 4507
against a non-existent /settings/probe endpoint.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added the frontend Frontend / React changes label Jun 21, 2026
master's required checks were already failing before this branch, blocking
any merge. None relate to the salt-api change; all are drift between evolved
code and stale assertions:

- ruff: sort import block in baselines.py:create_baseline
- mypy: coerce tracing resolved_service to str (was str | None in dict value)
- test_promote_topology_560: master api_url is now :4507, not :8080
- test_toast_dismiss_timing: error toasts auto-dismiss at 8000ms (#688
  superseded #159's never-dismiss) — assertion updated, not the code
- test_workers_bugs: scope the maintenance_mode grep to the whole
  sync_minion_presence function (it grew past 3000 chars with #689)
- test_drift_task: mock the extra Node lookup find_baseline_for_node_sync
  now issues to derive os_family
- test_llm_assistant_history_fix: assert streamQuery(prompt, history) after
  the mutation->stream refactor; the #303 history-before-addMessage guarantee
  is unchanged

Verified locally: 2770 unit tests pass, services coverage 84.11%, ruff+mypy clean.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added the test Test coverage improvement label Jun 21, 2026
@github-actions

Copy link
Copy Markdown

Coverage Report

84.2% on fleet_platform/services/ (gate: 80%)

Gate passed

@hellodk
hellodk merged commit 1b3ba19 into master Jun 21, 2026
9 of 12 checks passed
@hellodk
hellodk deleted the 2026-06-21-hqr3 branch June 21, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend Frontend / React changes test Test coverage improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant