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.
This commit is contained in:
Kristoffer Dalby
2026-06-18 12:26:58 +00:00
parent 67e0f34527
commit f6aea642d3
14 changed files with 22 additions and 24 deletions
+4 -2
View File
@@ -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**:
+1 -2
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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,
+4 -5
View File
@@ -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.
+1 -1
View File
@@ -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)
+2 -3
View File
@@ -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
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -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)
}
+1 -1
View File
@@ -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
+1 -1
View File
@@ -155,7 +155,7 @@ const (
Address = "address"
)
// gRPC fields.
// Request fields.
const (
Client = "client"
Request = "request"
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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.
+2 -3
View File
@@ -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 <key>`),
except over the local unix socket where filesystem permissions are the