mirror of
https://github.com/usestrix/strix.git
synced 2026-11-15 09:11:26 +00:00
Merge 9a73ba0f76 into cb581bf93d
This commit is contained in:
commit
eafdfde1fb
3 changed files with 72 additions and 5 deletions
|
|
@ -191,7 +191,11 @@ When remote vars are set, Strix dual-writes telemetry to both local JSONL and th
|
|||
</ParamField>
|
||||
|
||||
<ParamField path="DOCKER_HOST" type="string">
|
||||
Docker daemon address, for example `unix:///var/run/docker.sock` or `tcp://10.0.0.5:2375`. When not set, Strix connects to the same daemon as the `docker` CLI: the current docker context (`docker context use`), then the default socket. Docker Desktop, OrbStack and Colima register their sockets as contexts, so no extra configuration is needed for them.
|
||||
Docker daemon address, for example `unix:///var/run/docker.sock` or `tcp://10.0.0.5:2375`. When not set, Strix uses `DOCKER_CONTEXT`, then the saved current context (`docker context use`), then the default socket. Docker Desktop, OrbStack and Colima register their sockets as contexts, so no extra configuration is needed for them.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="DOCKER_CONTEXT" type="string">
|
||||
Select a Docker context for this shell without changing the saved current context. Used when `DOCKER_HOST` is unset. A missing context is an error; Strix does not silently fall back to another daemon. Set to `default` to use the SDK's default connection settings.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="STRIX_RUNTIME_BACKEND" default="docker" type="string">
|
||||
|
|
|
|||
|
|
@ -44,13 +44,13 @@ class DockerConnectionError(RuntimeError):
|
|||
|
||||
|
||||
def resolve_docker_endpoint(environ: dict[str, str] | None = None) -> DockerEndpoint:
|
||||
"""``DOCKER_HOST``, else the current docker context, else the SDK default."""
|
||||
"""``DOCKER_HOST``, shell/saved context, then the SDK default."""
|
||||
env = os.environ if environ is None else environ
|
||||
host = env.get("DOCKER_HOST", "").strip()
|
||||
if host:
|
||||
return DockerEndpoint(host, "DOCKER_HOST")
|
||||
|
||||
name = get_current_context_name()
|
||||
name = env.get("DOCKER_CONTEXT", "").strip() or get_current_context_name()
|
||||
if name == DEFAULT_CONTEXT:
|
||||
return DockerEndpoint(None, "default socket")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import importlib
|
||||
import json
|
||||
from types import SimpleNamespace
|
||||
from typing import Any, cast
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
import pytest
|
||||
from docker.errors import DockerException
|
||||
|
|
@ -19,6 +21,10 @@ from strix.runtime.docker_connection import (
|
|||
)
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
cli_utils: Any = importlib.import_module("strix.interface.utils")
|
||||
|
||||
|
||||
|
|
@ -34,7 +40,9 @@ def _sdk_error(inner: BaseException) -> DockerException:
|
|||
|
||||
def test_docker_host_wins_over_context(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(docker_connection, "get_current_context_name", lambda: "desktop-linux")
|
||||
endpoint = resolve_docker_endpoint({"DOCKER_HOST": "tcp://10.0.0.5:2375"})
|
||||
endpoint = resolve_docker_endpoint(
|
||||
{"DOCKER_HOST": "tcp://10.0.0.5:2375", "DOCKER_CONTEXT": "selected"}
|
||||
)
|
||||
assert endpoint == DockerEndpoint("tcp://10.0.0.5:2375", "DOCKER_HOST")
|
||||
|
||||
|
||||
|
|
@ -56,6 +64,61 @@ def test_default_context_uses_the_sdk_default(monkeypatch: pytest.MonkeyPatch) -
|
|||
assert resolve_docker_endpoint({}) == DockerEndpoint(None, "default socket")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("selected", "expected_host"),
|
||||
[
|
||||
("selected", "unix:///tmp/strix-selected.sock"),
|
||||
("default", None),
|
||||
("", "unix:///tmp/strix-saved.sock"),
|
||||
],
|
||||
)
|
||||
def test_shell_context_overrides_the_saved_context(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path: Path,
|
||||
selected: str,
|
||||
expected_host: str | None,
|
||||
) -> None:
|
||||
"""Read a real Docker context store, without contacting any daemon."""
|
||||
(tmp_path / "config.json").write_text(json.dumps({"currentContext": "saved"}))
|
||||
for name in ("saved", "selected"):
|
||||
context_id = hashlib.sha256(name.encode()).hexdigest()
|
||||
metadata = tmp_path / "contexts" / "meta" / context_id / "meta.json"
|
||||
metadata.parent.mkdir(parents=True)
|
||||
metadata.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"Name": name,
|
||||
"Metadata": {},
|
||||
"Endpoints": {
|
||||
"docker": {
|
||||
"Host": f"unix:///tmp/strix-{name}.sock",
|
||||
"SkipTLSVerify": True,
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
monkeypatch.setenv("DOCKER_CONFIG", str(tmp_path))
|
||||
monkeypatch.setenv("DOCKER_CONTEXT", selected)
|
||||
monkeypatch.delenv("DOCKER_HOST", raising=False)
|
||||
|
||||
assert resolve_docker_endpoint().host == expected_host
|
||||
|
||||
|
||||
def test_missing_shell_context_does_not_fall_back_to_saved_context(
|
||||
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
||||
) -> None:
|
||||
(tmp_path / "config.json").write_text(json.dumps({"currentContext": "default"}))
|
||||
monkeypatch.setenv("DOCKER_CONFIG", str(tmp_path))
|
||||
monkeypatch.setenv("DOCKER_CONTEXT", "missing")
|
||||
monkeypatch.delenv("DOCKER_HOST", raising=False)
|
||||
|
||||
with pytest.raises(
|
||||
DockerConnectionError, match="docker context 'missing' is selected but does not exist"
|
||||
):
|
||||
resolve_docker_endpoint()
|
||||
|
||||
|
||||
def test_missing_or_broken_current_context_is_an_error(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(docker_connection, "get_current_context_name", lambda: "gone")
|
||||
monkeypatch.setattr(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue