From f6aea642d3350a5d71779fbe51faa5246dd23c27 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Thu, 18 Jun 2026 12:26:58 +0000 Subject: [PATCH] all: scrub stale gRPC references from comments and docs Reword comments and docs that still named the removed gRPC stack, rename the GRPCSortable test interface, and drop the dead gRPC port note from the dev README. --- AGENTS.md | 6 ++++-- cmd/dev/README.md | 3 +-- cmd/headscale/cli/client.go | 2 +- hscontrol/api/v1/apikeys.go | 2 +- hscontrol/api/v1/convert.go | 9 ++++----- hscontrol/api/v1/health.go | 2 +- hscontrol/api/v1/server.go | 5 ++--- hscontrol/auth_test.go | 2 +- hscontrol/servertest/apiv1_users_test.go | 2 +- hscontrol/state/persist_test.go | 2 +- hscontrol/util/zlog/zf/fields.go | 2 +- integration/README.md | 2 +- integration/acl_test.go | 2 +- openapi/v1/headscale.yaml | 5 ++--- 14 files changed, 22 insertions(+), 24 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7fc325c6..000e5d1e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -133,9 +133,11 @@ headscale/ ### `hscontrol/` packages -- `app.go`, `handlers.go`, `grpcv1.go`, `noise.go`, `auth.go`, `oidc.go`, +- `app.go`, `handlers.go`, `noise.go`, `auth.go`, `oidc.go`, `poll.go`, `metrics.go`, `debug.go`, `tailsql.go`, `platform_config.go` — top-level server files +- `api/v1/` — the ogen-backed v1 HTTP API handlers (`server.go`, + `convert.go`, `errors.go`, per-resource handler files) - `state/` — central coordinator (`state.go`) and the copy-on-write `NodeStore` (`node_store.go`). All cross-subsystem operations go through `State`. @@ -209,7 +211,7 @@ both. This is a load-bearing architectural rule. - `SetTags` validation is enforced by `validateNodeOwnership()` in `hscontrol/state/tags.go`. - Examples and edge cases live in `hscontrol/types/node_tags_test.go` - and `hscontrol/grpcv1_test.go` (`TestSetTags_*`). + and the SetTags tests in `hscontrol/servertest/apiv1_nodes_test.go`. **Don't do this**: diff --git a/cmd/dev/README.md b/cmd/dev/README.md index 46da415d..f703f442 100644 --- a/cmd/dev/README.md +++ b/cmd/dev/README.md @@ -42,8 +42,7 @@ go tool mts node1 status | `--port` | 8080 | Headscale listen port | | `--keep` | false | Keep state directory on exit | -The metrics/debug port is `port + 1010` (default 9090) and the gRPC -port is `port + 42363` (default 50443). +The metrics/debug port is `port + 1010` (default 9090). ## What it does diff --git a/cmd/headscale/cli/client.go b/cmd/headscale/cli/client.go index 36c97585..c582f19e 100644 --- a/cmd/headscale/cli/client.go +++ b/cmd/headscale/cli/client.go @@ -96,7 +96,7 @@ func localSocketClient(socketPath string) (*apiv1.Client, error) { // dialSocketWaiting connects to the local unix socket, retrying while it is // still absent. headscale removes and rebinds the socket during startup, so a // CLI command issued right after "systemctl start" can beat the server to it. -// This mirrors the old blocking gRPC dial, which retried until the CLI timeout. +// This mirrors the old blocking dial, which retried until the CLI timeout. func dialSocketWaiting(ctx context.Context, socketPath string) (net.Conn, error) { var dialer net.Dialer diff --git a/hscontrol/api/v1/apikeys.go b/hscontrol/api/v1/apikeys.go index 81bb4f13..5109285c 100644 --- a/hscontrol/api/v1/apikeys.go +++ b/hscontrol/api/v1/apikeys.go @@ -77,7 +77,7 @@ func (s *Server) DeleteApiKey(_ context.Context, params oas.DeleteApiKeyParams) } // apiKeyByIDOrPrefix looks up an API key by exactly one of id or prefix. -// Providing neither or both is a 400, matching the gRPC contract. +// Providing neither or both is a 400. func (s *Server) apiKeyByIDOrPrefix( id uint64, prefix string, diff --git a/hscontrol/api/v1/convert.go b/hscontrol/api/v1/convert.go index a28cf2f8..588f2a92 100644 --- a/hscontrol/api/v1/convert.go +++ b/hscontrol/api/v1/convert.go @@ -11,12 +11,11 @@ import ( // This file converts the state-layer types into the ogen API types. It reads // the copy-on-write view types (NodeView, UserView, PreAuthKeyView) directly so -// no node/user is deep-copied on the read path, and reproduces exactly what the -// previous proto builders emitted — username fallback, masked key prefixes, -// online computation, the register-method enum. +// no node/user is deep-copied on the read path, and reproduces the same fields +// the previous API emitted — username fallback, masked key prefixes, online +// computation, the register-method enum. // -// Unlike grpc-gateway (which marshalled with EmitUnpopulated), these converters -// omit zero-value and absent fields — empty strings, false booleans, zero +// These converters omit zero-value and absent fields — empty strings, false booleans, zero // numbers, empty arrays, nil timestamps/objects, and the unspecified register // method. See docs/v1-ogen/CHANGES.md. diff --git a/hscontrol/api/v1/health.go b/hscontrol/api/v1/health.go index 2e23d09b..92e952d5 100644 --- a/hscontrol/api/v1/health.go +++ b/hscontrol/api/v1/health.go @@ -7,7 +7,7 @@ import ( ) // Health reports server health, including database connectivity. A failed -// database ping is a 500; the gRPC implementation likewise returned the ping +// database ping is a 500; the previous implementation likewise returned the ping // error (the body's databaseConnectivity flag was never observable on failure). func (s *Server) Health(ctx context.Context) (*oas.HealthOK, error) { err := s.state.PingDB(ctx) diff --git a/hscontrol/api/v1/server.go b/hscontrol/api/v1/server.go index dcecb4f6..b421367b 100644 --- a/hscontrol/api/v1/server.go +++ b/hscontrol/api/v1/server.go @@ -19,9 +19,8 @@ import ( // Server implements the generated [oas.Handler] and [oas.SecurityHandler]. // -// Operations that have not been migrated from the gRPC stack yet are inherited -// from [oas.UnimplementedHandler] and return 501; each resource group replaces -// its stubs as it is converted. +// Any operation not implemented here is inherited from +// [oas.UnimplementedHandler] and returns 501; every operation is implemented. type Server struct { oas.UnimplementedHandler diff --git a/hscontrol/auth_test.go b/hscontrol/auth_test.go index ed294f3c..e46aa970 100644 --- a/hscontrol/auth_test.go +++ b/hscontrol/auth_test.go @@ -4052,7 +4052,7 @@ func TestHandleNodeFromPreAuthKey_OldUserNil_NoPanic(t *testing.T) { } // TestHandleNodeFromAuthPath_OldUserNil_NoPanic is the parallel guard -// for the gRPC/OIDC entry point. Same orphan shape as +// for the OIDC/auth-path entry point. Same orphan shape as // TestHandleNodeFromPreAuthKey_OldUserNil_NoPanic; HandleNodeFromAuthPath // has its own oldUser.Name() log line in the existingNodeOwnedByOtherUser // branch and panics independently of the noise registration path. diff --git a/hscontrol/servertest/apiv1_users_test.go b/hscontrol/servertest/apiv1_users_test.go index bf4ee016..324ce889 100644 --- a/hscontrol/servertest/apiv1_users_test.go +++ b/hscontrol/servertest/apiv1_users_test.go @@ -72,7 +72,7 @@ func TestAPIv1_RenameUser(t *testing.T) { _, err = srv.State().GetUserByName("alice2") require.NoError(t, err) - // Unknown user is a 404 (the gRPC stack returned 500 here). + // Unknown user is a 404 (the previous implementation returned 500 here). _, err = client.RenameUser(ctx, apiv1.RenameUserParams{OldID: 99999, NewName: "ghost"}) requireProblem(t, err, http.StatusNotFound) } diff --git a/hscontrol/state/persist_test.go b/hscontrol/state/persist_test.go index 0be0b411..43d6cbf6 100644 --- a/hscontrol/state/persist_test.go +++ b/hscontrol/state/persist_test.go @@ -83,7 +83,7 @@ func persistTestConfig(dbPath string) *types.Config { } // TestPersistEmptyApprovedRoutes covers the State.SetApprovedRoutes -// path. The gRPC handler builds the slice via append from a nil +// path. The handler builds the slice via append from a nil // declaration, so when the operator passes `-r ""` the persist layer // receives a nil []netip.Prefix. GORM's struct Updates skips nil // slices, so the column would stay populated with the previously diff --git a/hscontrol/util/zlog/zf/fields.go b/hscontrol/util/zlog/zf/fields.go index 45edd1da..6661d8fe 100644 --- a/hscontrol/util/zlog/zf/fields.go +++ b/hscontrol/util/zlog/zf/fields.go @@ -155,7 +155,7 @@ const ( Address = "address" ) -// gRPC fields. +// Request fields. const ( Client = "client" Request = "request" diff --git a/integration/README.md b/integration/README.md index 5511a113..e4e4a518 100644 --- a/integration/README.md +++ b/integration/README.md @@ -159,7 +159,7 @@ for _, client := range allClients { Typical blocking operations: any `tailscale set` (routes, exit node, accept-routes, ssh), node registration via the CLI, user creation via -gRPC. +the CLI. ### The four rules diff --git a/integration/acl_test.go b/integration/acl_test.go index b8be400b..9f9007c3 100644 --- a/integration/acl_test.go +++ b/integration/acl_test.go @@ -2634,7 +2634,7 @@ func TestACLTagPropagation(t *testing.T) { // Step 3: Verify final NetMap visibility first (fast signal that // the [tailcfg.MapResponse] propagated to the client). - // The full propagation chain (docker exec → gRPC → state update → + // The full propagation chain (docker exec → API → state update → // batcher delay → [tailcfg.MapResponse] → noise transport → client processing) // can take over 120s on congested CI runners, so use a generous // base timeout. diff --git a/openapi/v1/headscale.yaml b/openapi/v1/headscale.yaml index 635495f4..e20d3a06 100644 --- a/openapi/v1/headscale.yaml +++ b/openapi/v1/headscale.yaml @@ -5,9 +5,8 @@ info: description: | HTTP API for managing a Headscale control server: users, pre-auth keys, nodes, API keys, and ACL policy. This is the v1 API, served under - `/api/v1`. It is the OpenAPI 3.0 successor to the previous - gRPC/grpc-gateway facade and is the single source of truth for the API - contract. + `/api/v1`. It is the OpenAPI 3.0 definition and the single source of truth + for the API contract. Authentication is a bearer API key (`Authorization: Bearer `), except over the local unix socket where filesystem permissions are the