Description
Thin client fails to connect when --cwd does not exist locally
Summary
In client/server mode (CRUSH_CLIENT_SERVER=1), crush --cwd <path> fails
to connect unless <path> already exists on the client's local
filesystem — even though the path refers to a workspace that lives entirely
on the server. The mismatch shows up exactly where thin clients matter
most: connecting over TCP to a remote machine whose project paths do not
exist locally.
Steps to reproduce
- Start a Crush server on a machine (or container) that has a project at
/srv/projects/app:
CRUSH_CLIENT_SERVER=1 crush server --host tcp://0.0.0.0:8090
- From a different machine (or a container without that directory) run:
CRUSH_CLIENT_SERVER=1 crush --cwd /srv/projects/app --host tcp://<crush-server-ip>:8090
(where /srv/projects/app does not exist on the client machine)
Expected behavior
The thin client connects, and the server opens/creates the workspace at
/srv/projects/app on the machine where the server runs.
Actual behavior
The client fails immediately with a local filesystem error (the client
attempts to chdir into --cwd), so a thin client can never address a
remote project whose path is absent locally. Users work around it by
creating dummy directories (mkdir -p /srv/projects/app) on every machine
they connect from, which is brittle and confusing — the directory contents
are never used by the client.
Root cause
connectToServer resolved --cwd through ResolveCwd, which exists for
local mode: it validates the directory and calls os.Chdir. In
client/server mode the working directory belongs to the server process —
its tools execute there — so the client has no business chdirring into it.
Suggested fix
Split the resolution paths:
- Local mode: keep
ResolveCwd (validate + os.Chdir), because the
in-process agent runs its tools there.
- Client mode: accept
--cwd verbatim — absolutize it against the
client's process cwd without checking existence and without chdirring.
A bogus path should then surface as an error from the server's workspace
creation, which is where the path is actually meaningful.
Reference implementation: resolveClientCwd in internal/cmd/root.go,
covered by internal/cmd/cwd_test.go.
Related friction
While fixing this we also noticed that exiting a thin client could tear
down workspace state on the server for in-flight work, and that crush session subcommands did not route through the server in client mode.
Both are addressed alongside this fix in the same series.
Version
7dead4d
Environment
alpine linux musl
Description
Thin client fails to connect when
--cwddoes not exist locallySummary
In client/server mode (
CRUSH_CLIENT_SERVER=1),crush --cwd <path>failsto connect unless
<path>already exists on the client's localfilesystem — even though the path refers to a workspace that lives entirely
on the server. The mismatch shows up exactly where thin clients matter
most: connecting over TCP to a remote machine whose project paths do not
exist locally.
Steps to reproduce
/srv/projects/app:/srv/projects/appdoes not exist on the client machine)Expected behavior
The thin client connects, and the server opens/creates the workspace at
/srv/projects/appon the machine where the server runs.Actual behavior
The client fails immediately with a local filesystem error (the client
attempts to
chdirinto--cwd), so a thin client can never address aremote project whose path is absent locally. Users work around it by
creating dummy directories (
mkdir -p /srv/projects/app) on every machinethey connect from, which is brittle and confusing — the directory contents
are never used by the client.
Root cause
connectToServerresolved--cwdthroughResolveCwd, which exists forlocal mode: it validates the directory and calls
os.Chdir. Inclient/server mode the working directory belongs to the server process —
its tools execute there — so the client has no business chdirring into it.
Suggested fix
Split the resolution paths:
ResolveCwd(validate +os.Chdir), because thein-process agent runs its tools there.
--cwdverbatim — absolutize it against theclient's process cwd without checking existence and without chdirring.
A bogus path should then surface as an error from the server's workspace
creation, which is where the path is actually meaningful.
Reference implementation:
resolveClientCwdininternal/cmd/root.go,covered by
internal/cmd/cwd_test.go.Related friction
While fixing this we also noticed that exiting a thin client could tear
down workspace state on the server for in-flight work, and that
crush sessionsubcommands did not route through the server in client mode.Both are addressed alongside this fix in the same series.
Version
7dead4d
Environment
alpine linux musl