mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(cli): terminate ephemeral proxy if write_pid_record itself fails
write_pid_record ran before the try/except that terminates the proxy and clears the pid record on failure, so a write_pid_record error (disk full, permission error creating ~/.litellm/autorouter/) left the just-launched proxy running with no pid record on disk at all -- exactly the state lite autoroute down needs a pid record to recover from. Moved it inside the try block alongside poll_liveliness.
This commit is contained in:
parent
4dedd60868
commit
7c3c242ecd
2 changed files with 33 additions and 2 deletions
|
|
@ -101,11 +101,11 @@ def up() -> None:
|
|||
port = allocate_free_port()
|
||||
base_url = f"http://127.0.0.1:{port}"
|
||||
process = launch_proxy(CONFIG_PATH, port, LOG_PATH)
|
||||
write_pid_record(PidRecord(pid=process.pid, port=port, config_path=str(CONFIG_PATH), log_path=str(LOG_PATH)))
|
||||
|
||||
try:
|
||||
write_pid_record(PidRecord(pid=process.pid, port=port, config_path=str(CONFIG_PATH), log_path=str(LOG_PATH)))
|
||||
poll_liveliness(base_url, LOG_PATH, process)
|
||||
except ProcessLaunchError as e:
|
||||
except (ProcessLaunchError, OSError) as e:
|
||||
terminate(process.pid)
|
||||
clear_pid_record()
|
||||
raise click.ClickException(str(e))
|
||||
|
|
|
|||
|
|
@ -203,6 +203,37 @@ class TestUpCommand:
|
|||
assert not backup_path.exists()
|
||||
assert json.loads(claude_settings_path.read_text()) == original_settings
|
||||
|
||||
def test_terminates_ephemeral_proxy_when_write_pid_record_fails(self, monkeypatch, tmp_path):
|
||||
"""write_pid_record runs before poll_liveliness -- if it raises (disk full, permission
|
||||
error creating ~/.litellm/autorouter/), the just-launched proxy must still be terminated,
|
||||
not left running with no pid record for `lite autoroute down` to ever find."""
|
||||
config_path, _log_path, claude_settings_path, backup_path, _pid_record_path = _patch_paths(
|
||||
monkeypatch, tmp_path
|
||||
)
|
||||
config_path.write_text(yaml.safe_dump({"model_list": []}))
|
||||
original_settings = {"theme": "dark"}
|
||||
claude_settings_path.write_text(json.dumps(original_settings))
|
||||
|
||||
fake_process = FakeProcess(pid=888)
|
||||
terminate_calls = []
|
||||
|
||||
def _raise_os_error(*args, **kwargs):
|
||||
raise OSError("disk full")
|
||||
|
||||
monkeypatch.setattr(commands_module, "launch_proxy", lambda *a, **k: fake_process)
|
||||
monkeypatch.setattr(commands_module, "write_pid_record", _raise_os_error)
|
||||
monkeypatch.setattr(commands_module, "allocate_free_port", lambda: 34567)
|
||||
monkeypatch.setattr(commands_module, "terminate", lambda pid, **k: terminate_calls.append(pid))
|
||||
monkeypatch.setattr(commands_module.secrets, "token_urlsafe", lambda n: "fixed-master-key")
|
||||
|
||||
result = self.runner.invoke(up)
|
||||
|
||||
assert result.exit_code != 0
|
||||
assert "disk full" in result.output
|
||||
assert terminate_calls == [888]
|
||||
assert not backup_path.exists()
|
||||
assert json.loads(claude_settings_path.read_text()) == original_settings
|
||||
|
||||
def test_terminates_ephemeral_proxy_when_claude_settings_is_corrupt(self, monkeypatch, tmp_path):
|
||||
"""The health check can pass and the proxy can come up fine, but if
|
||||
~/.claude/settings.json turns out to be corrupt, the just-started proxy must not be left
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue