Step 2 of the interactive-job UX work: `-I --tty` now attaches the session
to the submitting terminal by default instead of opening a browser.
Producer/consumer shape (user clusters cannot reach worker ttyd ports):
xcecli (-I --tty, raw terminal)
<-> GET /xce/v1/jobs/:id/attach (JWT auth + job:control ownership)
<-> ws://worker:ttyd-port/ws (ttyd)
apiserver (controllers/job_attach.go):
- new websocket relay endpoint, route gated by RequirePermission("job:control");
owner may always attach, others need a job:control scope covering the owner
- JWT accepted from the Authorization header or ?token= query param
(browser WebSocket API cannot set headers)
- bidirectional frame pump with policy close codes: 4000 = cannot reach the
session on the worker, 4001 = session ended
- the worker hop dials with the "tty" websocket subprotocol: ttyd 1.7.7
completes the handshake without it but then stays silent (verified against
the deployed binary)
xcecli (cmd/jobs/attach.go):
- attach client: dials the relay, raw mode via golang.org/x/term, ttyd
wire format (TEXT hello {"AuthToken",columns,rows}; binary frames
'0'+input, '1'+resize JSON, output '0' to stdout), SIGWINCH resize
forwarding, terminal restored on every exit path
- submit.go: --browse flag opens the web URL instead of attaching (TTY jobs
attach by default; XJOB/VNC keeps the browser path); the URL line is
always printed as a record
- waitForInteractiveURL no longer fails when the job is RUN but the worker's
start report (carrying the URL) has not landed yet -- poll and retry
Verified on t1: raw-client and real-xcecli attach round trips through the
relay (echo both ways), kill -> EXIT with URL retained, batch jobs unaffected,
all daemons healthy. Suites: meson 'apiserver backend' 1/1, CGO_ENABLED=0
controllers/router and xcecli tests green.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Cause: ConfigFileProvider.Authenticate compared the stored plaintext
password with != (timing side channel, passwords readable from the file),
and config/auth.yaml shipped admin/admin, user1/user1 etc. as plaintext
with nothing reporting that a default credential was active.
Fix: auth.yaml passwords may be bcrypt hashes (golang.org/x/crypto/bcrypt,
v0.23.0 as already pinned in go.mod, now vendored); plaintext entries are
still accepted but compared in constant time (SHA-256 + subtle), and an
unknown user costs the same bcrypt work. The provider reports startup
warnings (SecurityWarner, logged by main) for every plaintext entry and for
every shipped default credential still active. The shipped auth.yaml and
auth.yaml.example now store bcrypt hashes of the same dev passwords, so
tests/regression/run.sh (admin/admin) keeps working. tools/encrypt gains
-action=hash to generate entries.
Tests: TestConfigFileProvider_BcryptPassword,
TestConfigFileProvider_SecurityWarnings, TestShippedAuthConfig_HashedDefaults.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Nix build previously fetched Go modules from goproxy.cn and Python
build deps from PyPI during the build phase, relying on network leaking
into the sandbox. This is non-reproducible and breaks whenever the
sandbox resolver is unreachable (e.g. pc13v's loopback dnsmasq).
Go:
- Vendor all three modules (frontend/apiserver, frontend/xcecli,
autoscaler/providers/baidu/src/bcctool) and commit vendor/ trees.
- tools/go_build now builds with GOFLAGS=-mod=vendor and GOPROXY=off
instead of GOPROXY=https://goproxy.cn.
Python (xceadmin):
- Add setuptools + wheel to xce.nix nativeBuildInputs.
- meson-build.sh installs with pip --no-build-isolation --no-index
--no-deps so no PyPI access happens at build time.
xceadmin install script:
- Invoke meson-install.sh via find_program('bash') instead of relying
on its #!/usr/bin/env bash shebang, which fails in the Nix install
sandbox (no /usr/bin/env -> 'could not be run').
Cleanup:
- Drop now-unneeded cacert and impureEnvVars=[HOME] from xce.nix and
xcecli.nix (they only existed to enable the impure network fetch).
Docs:
- README build guide: drop '--option sandbox false' from nix build /
nix bundle commands, note the build is now hermetic, and document the
go mod vendor + git add vendor/ maintenance workflow.
Verified: nix build .#xcecore, .#xcecore_debug, .#xcecli, and .#xce all
succeed with the sandbox enabled.