Repository navigation
refactor: move Tailscale behind a transport contract - #3685
Merged
Merged
Conversation
Add @stim-cli/transport, the contract and loader for stim-server transports, and @stim-cli/transport-tailscale, which holds the Tailscale driver moved out of packages/server. stim-server loads the Tailscale transport through the loader and reaches peer identity and its extra listen addresses only through the contract. The /health fields, route.setup and paired machine pinning still read the Tailscale transport directly until the generic status and resolve capabilities land. No behavior change. Refs #3681.
Listen on the bind addresses of every transport, not only of those that report changes, and give the Tailscale transport bind addresses only when it has a monitor, as before. The loader refuses a capability that is not a function and closes a transport that a factory creates after the load timed out. stim-server binds an identity to the transport that answered. A service install from package files is keyed by those files too, so an update that changes only a dependency package installs it. Align the design with the phase 1 contract and list the new packages in the READMEs. Refs #3681.
The server's workspace closure grows with the transport and agent driver packages, past the old limit of 8. Refs #3681.
Collaborator
Author
|
Human review: reviewed at b2e5e99
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
stim-server reaches phones and other machines only through Tailscale, and
server.tscallswhois,serveRoute,setupServeRouteandreadRawTailscaleStatusdirectly. There is no place to plug in another transport. This is phase 1 of the design, which is also in this PR. Later phases add local, ngrok and cloudflared transports, a key-based peer identity and the generic status surface for Desktop and the mobile app.Solution
@stim-cli/transportis a contract-only package, in the same style as@stim-cli/cache: a module exportsapiVersion,idandcreateTransport().loadTransport()never throws: a missing module, a wrongapiVersion, a failing factory, a capability that is not a function or a 10 s timeout all come back asunavailable, and a transport created after the timeout is closed. The caller passes the import function, so bundled first-party transports use a plainimport()and tests can mock them.@stim-cli/transport-tailscaleholdstailscale.tsandtailscale-monitor.ts, moved withgit mvand otherwise left as they were, plusplanServe.service-plist.tsre-exportsplanServesosetup.tsandservice.tskeep their imports.stim-serverloads the Tailscale transport through the loader.server.tsgets peer identity (identify) and its extra listen addresses (bindAddresses,watch) only through the contract. The server listens on the bind addresses of every transport that has them. Only an identity returned by the Tailscale transport maps to the existing on-disk{ kind: 'tailnet', nodeId, ... }record, sodevices.jsonand the other registries do not change./healthtailscaleandroutefields,route.setup, and the raw status that pins paired machines in the hosted relay and machine updates. They move onto genericstatus,setupandresolvein phases 2 and 3. The CLI side (core/state/tailnet.ts,offload/) is untouched here.ServerOptionsstill acceptstailscale,tailscaleStateandtailscaleMonitorand builds the transport from them, so the existing server tests run as before.Packaging changes that come with two new published packages:
dependenciesapps/desktop/scripts/server-runtime.mjs)PACKAGE_DIRSand two publish steps before@stim-cli/serverrelease-prep, runtime-floor and the RELEASE.md and recovery docsBefore the next release tag,
@stim-cli/transportand@stim-cli/transport-tailscaleneed placeholder publications and trusted publishers. Follow "First publication of a NEW package" in docs/release-recovery.md. Without them, the publish job fails after the earlier packages have published.Machine updates offer the two new packages to remote Macs from a checkout, so the expected package lists in
machine-update.test.tsgrow. That makes 7 packages. With the agent driver packages from #3686 it would be 9, past the receiver's old limit of 8, soMAX_PACKAGESinserver-update.tsgoes to 16. Remote Macs on older releases still accept at most 8 in a checkout update; release updates are unaffected.service update --fromnamed the install directory by version, Stim build and a digest of the server's owndist. Once the Tailscale code lives in another package, an upload that changes only that package would reuse the old directory and report the update as already running. The directory name now also includes a digest of the uploaded package files. Release installs keep their old names.Test plan
tailscalebinary inserver.test.ts, thex-forwarded-forpeer cases,setup*.test.ts,registry.test.tsandhosted-relay*.test.ts. Three tests changed only because they mocked module paths that moved:setup-endpoint.test.tsnow stubs the transport'sidentify, andshutdown.test.tsandloopback-only.test.tsstubcreateTransport.packages/transport/__tests__/load.test.ts: a module that does not load, a differentapiVersion, no factory, a throwing factory, a non-transport result, a capability that is not a function, a load that never settles, and a factory that finishes after the timeout.server.test.ts: the server listens on the bind addresses of a transport withoutwatch.install-from.compat.test.ts(real npm): reinstalling with only@stim-cli/transport-tailscalechanged goes to a new directory.dist/stim-server.mjs --loopback-onlywith a temporarySTIM_HOMEon a Mac with Tailscale running./healthreturned200withtailscale: { state: 'running', dnsName: '<mac>.ts.net' }androute: { state: 'missing', port: 7444 }, read through the loaded transport.pnpm test: 8912 passed. Format, lint, build, typecheck, knip,rpc:checkandtest:runtimeare clean.Refs #3681