This repository was archived by the owner on Jul 13, 2025. It is now read-only.
Fork Sync: Update from parent repository - #36
Open
github-actions[bot] wants to merge 1924 commits into
Open
Conversation
The override comment didn't work as expected. (I'll be updating the policytest package to handle this) Updates tailscale/corp#13972 Change-Id: Ic5c16eed09c8cb5fa8dab37d43cf05f8dfa75d49 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
prometheus/common v0.66/v0.67 introduced a mandatory model.ValidationScheme on expfmt.TextParser as part of prepping for UTF-8 metric/label names in Prometheus 3.0. The zero value is intentionally UnsetValidation, which panics on the first call to IsValidMetricName / IsValidLabelName with Invalid name validation scheme requested: unset so the long-standing "var parser expfmt.TextParser" pattern crashes at runtime. Several big downstreams have hit the same sharp edge: thanos-io/thanos#8823 grafana/loki#21401 Switch our two callers (parseMetrics in tsnet's TestUserMetricsByteCounters and the client-metrics scraper in tstest/natlab/vmtest) to the new expfmt.NewTextParser constructor with model.LegacyValidation. LegacyValidation matches the classic ASCII metric/label naming rules that tailscaled's exporter uses today; if and when we ever emit a metric with a UTF-8 name, we can revisit. Goes to v0.69.0 (the latest at the time of writing) rather than v0.67.5 so we pick up the unrelated security fixes for cross-host redirects. Done in advance so a follow-up change can pull in github.com/tailscale/policybottest (which depends on palantir/policy-bot, which transitively requires prometheus/common at v0.67+) without dragging this debugging into that PR. Updates tailscale/corp#13972 Change-Id: I4b37db9ad3bebef1a32d9020bf6f8790bab25336 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add a .policy-tests.yml file with tests exercising the policy that was just landed: the tailcfg/ control-protocol-owners gate, the "policybot-override:" comment escape hatch (including defaults-regression guards so the override rule does not silently accept a normal review or a 👍 comment), and the always-on "any tailscale/dev review" baseline. Updates tailscale/corp#13972 Change-Id: I42afb06b0771658c803512cb5de4701450c8a704 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
WhoIs lookups for an IPv6-mapped IPv4 address such as "::ffff:100.87.98.86" failed to match the node's canonical IPv4 address. Unmap the address before looking it up so these resolve. Fixes #20235 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Bouke van der Bijl <i@bou.ke>
Move all the FooForTest methods on LocalBackend to instead be methods on a new unexported forTest type which is then given out to callers in other packages via an exported ForTest method (panicking in non-test contexts) that returns that unexported type. This is unusual style (exported returning unexported) but declutters godoc and makes call sites both more explicit and easier to read without the "ForTest" suffix polluting the symbols. Now FooForTest() changes into ForTest().Foo(). This was motivated by a pending change moving a bunch of code out of LocalBackend into other packages that required adding more ForTest methods to LocalBackend to keep the tests (now in other packages) working. Instead, do this refactor now so the future change is prettier. Updates #12614 Updates #cleanup Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: Ib25e6d76d48dc8622ac3a955e0b1220d582e63a8
This was missing in the earlier f5eac39 and meant that tsnet users weren't getting (all of) acme support. Thanks to @ChaosInTheCRD and @BeckyPauley for debugging. Updates #12614 Updates #20252 Change-Id: I176a7b179b2ad3726aca484057f0aae7cc3561c8 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Tests in magicsock_test.go would routinely emit this warning: ## WARNING: (non-fatal) nil health.Tracker (being strict in CI): because they would run NewConn without initializing a health.Tracker. This patch initializes Conn correctly with a health.Tracker. It also fixes some missing Close calls that can be handled in t.Cleanup. Fixes #20263 Signed-off-by: Simon Law <sfllaw@tailscale.com>
`TestNetworkSendErrors/network-down` causes a data race because it tried to `tstest.Replace` the `checkNetworkDownDuringTests` global while `wgengine.Conn.networkDown` would read from it. This patch moves this flag into a field within the `wgengine.Conn` struct, so there’s no chance that two tests could trample on each other. It also renames this field to `Conn.checkNetworkUpDuringTests`, because `Conn.networkUp` is the name of the field that gets checked. Fixes #20260 Signed-off-by: Simon Law <sfllaw@tailscale.com>
…e/acme f5eac39 ("feature/acme, ipn/ipnlocal: start moving ACME/cert state into an extension") started to move the cert code into feature/acme but was meant as a baby step. This goes further, moving almost everything, leaving only some hooks in ipnlocal. When we later move "serve" support out to feature/serve, this will look a bit different in that the hooks currently in ipnlocal will move to feature/serve (cert support already depends on serve). As part of this, cert-related tests move to feaure/acme too, which means some test infra from ipnlocal now moves to shared ipnlocaltest. (it's not big at the moment, but I imagine it growing) Updates #12614 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: I9ea89aa9754f12d54b81751b6bd830f2664241ff
Currently, PeerAPI DNS is only allowed if
1. The peer is owned by the same user as this device, or
2. The node is an exit node or app connector
a. and the peer has access to a hypothetical DNS server at 0.0.0.0:53
(which approximately means "the peer has access to
autogroup:internet")
None of this is useful for conn25. This adds the most basic of hooks
(and converts the existing logic to a hook, which should improve clarity
and lead to the possibility of moving the existing checks into feature
packages in future).
There is an extra filter based on the name being queried that is
performed later. It refuses names in
tailcfg.DNSConfig.ExitNodeFilteredSet. That filter is not modified by
this change.
With this change, if conn25 is configured as a connector, then all
PeerAPI DNS queries are permitted (still subject to the
ExitNodeFilteredSet as noted above).
More work is required: the goal before release (i.e. the WIPCode check
is removed) is that each query should be checked against the list of
domains in the requested conn25 app. For now, this only verifies that
conn25 is configured (and does not include the autogroup:internet
check, which is not how conn25 grants will operate when implemented,
soon).
This change has been manually tested against the scenario outlined in
tailscale/corp#40117; unfortunately the code's structure makes writing a
unit test difficult. The more comprehensive changes needed for
tailscale/corp#40076 should include an integration test that covers this
case.
The hook must go in the ipnlocal package rather than the usual extension
host to prevent a circular dependency on the ipnlocal.PeerAPIHandler
interface. Registering PeerAPI handlers uses a similar strategy, likely
because of, at least in part, this same problem.
Updates tailscale/corp#40076
Fixes tailscale/corp#40117
Change-Id: I367714170b509d7a421f62672e5824b3590c2b9c
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
All issuances serialise through a single mutex in tailscaled. The old 300s timeout fired while a predecessor was legitimately mid-ACME, causing the queued loop to advance retryCount on a non-failure. 30m covers ~15 queued flows and works as a wedge detector against true hangs. Updates #20288 Updates #42164 Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
This adds a Created field to LoginProfile to normalize the sort order of login profiles presented in the various client GUIs. The default sort order for existing profiles remains unchanged and continues to be based on Name. Newly added profiles will be stamped at creation time and returned at the top of the list of unstamped profiles, sorted by creation date in descending order. The rationale is to ensure that all clients present the user's profile list in the same order, regardless of newly added accounts, name changes, or nickname overrides. The Mac client was recently updated to remove various custom profile sorting behaviors (tailscale/corp#43847). iOS, Android, and Windows do not currently perform GUI-level sorting, so this change should propagate to them seamlessly. updates tailscale/corp#43843 Signed-off-by: Will Hannah <willh@tailscale.com>
Adds two Gokrazy-based vmtests covering the tailscaled web client at
port 5252:
* TestWebClientLocalAccess enables the web client on a single node
and exercises the canonical owner session flow against the node's
own Tailscale IP: an unauthenticated GET /api/auth that identifies
the caller, a GET /api/auth/session/new that issues a
TS-Web-Session cookie, and a final GET /api/auth that reports
authorized=true with the cookie.
* TestWebClientRemoteAccess runs the same session flow from a peer
node on the same tailnet against a second target node's web
client, exercising netstack interception of incoming :5252
traffic, cross-node WhoIs, and the same-user "owner" path. It
then flips the test control server's AllNodesSameUser off,
re-logs in the client under a fresh identity, and asserts that
GET /api/auth/session/new returns 401 with body "not-owner" --
exercising the cross-user rejection in client/web/auth.go.
To make the natlab test environment exercise the same code path
as production (check mode, where the web client posts to
/machine/webclient/init via Noise and waits on a control-issued
auth URL), this also:
* Allowlists the natlab fake control hostname "control.tailscale"
in client/web/auth.go's controlSupportsCheckMode so the web
client follows the check-mode branch rather than the
no-check-mode shortcut that immediately marks new sessions
authenticated.
* Adds /machine/webclient/{init,wait} handlers to testcontrol.
init returns a placeholder auth ID and URL; wait returns
Complete=true immediately, so the web client's awaitUserAuth
resolves on its first call. Together these let the tests drive
the full check-mode session lifecycle without a real
browser-click loop.
To support the multi-request HTTP flows from the test harness,
this also adds:
* vmtest.Env.HTTPGetStatus, a sister of HTTPGet that returns the
upstream status code, body, and Set-Cookie cookies (as a
vmtest.HTTPResponse) and accepts cookies on the outgoing
request, so tests can drive flows that depend on cookie
continuity.
* Cookie pass-through in cmd/tta's /http-get handler: it forwards
the Cookie request header upstream and surfaces upstream
Set-Cookie response headers downstream. This is what lets
HTTPGetStatus carry a session cookie across requests.
Previously the only tests of the web client were in-process
httptest-based handler tests in client/web/web_test.go; nothing
exercised the actual port 5252 listener wiring, the cross-node
auth path, cookie-driven session state transitions through the
check-mode control round-trip, or the not-owner rejection end
to end.
Updates #13038
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: Idb01486a89b53ac02c6ad3358bcfcceca90dbc36
…date for Gokrazy Builds on top of the unsigned URL-based GAF update flow added previously (see referenced issue for context). The pkgs.tailscale.com server now publishes signed GAFs for the unstable track, with detached ed25519 signatures produced by pkgsign's signdist path (the same distsign scheme used for every other release artifact). This change consumes them. The URL-based path (tailscale update --gokrazy-update-from-url=URL) now verifies the signature by default using clientupdate/distsign.Client, which fetches distsign.pub from the root of the host serving the GAF and checks the .sig against the root keys embedded in this binary. The --unsigned flag stays for TestGokrazyUpdatesItselfToSameImage, whose in-test fileserver does not publish distsign.pub. The bare tailscale update path is now wired up for the Tailscale appliance image. It fetches <pkgs>/<track>/?mode=json, picks the GAF whose key matches the local device (vm-amd64, vm-arm64, or pi-arm64, where arm64 is split via /sys/firmware/devicetree/base/model), confirms the version with the user, and reuses the verified download path above. To avoid wiping a user's custom Gokrazy build that happens to include tailscaled, the bare update path is gated on hostinfo.Package == "tsapp", which is only set when the new ts_appliance build tag is present (mirroring the existing ts_package_container tag). The gokrazy/tsapp*/config.json files now pass GoBuildTags ["ts_appliance"] for the tailscale and tailscaled packages so monogok bakes the tag into the official appliance builds. The TS_FORCE_ALLOW_TSAPP_UPDATE env var is an escape hatch for callers who want to force the appliance update path on a non-appliance build. The URL-based path stays ungated since it requires explicit user intent (and is exercised by the natlab vmtest). Updates #20002 Change-Id: I7c7856a88bf3dffb9eb8d3e9111fad0b3906743c Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This adds the NotifyInitialPolicy watch option and the Policy field in Notify so that clients can receive the effective policy snapshot via IPN bus. This extends policyclient.Client so ipnlocal can get and watch policy snapshots, which is used by sysPolicyChanged to notify watchers. User-scoped policy store registration, management, and cleanup will be added in a follow-up Updates tailscale/corp#42259 Signed-off-by: kari <kari@tailscale.com>
Tailscaled had no way to seed device-scope syspolicy settings short of environment variables or a custom store wired up out of tree. Add a --syspolicy-file flag whose default points at a well-known JSON file that, when present, is parsed as a map[string]any and registered as a device-scope policy source. The default path is /etc/tailscale/syspolicy.json on every non-Windows platform (Linux, the BSDs, illumos/Solaris, and tailscaled-without-the-GUI on macOS) and %ProgramData%\Tailscale\syspolicy.json on Windows. The flag lets users running tailscaled by hand (development, custom installs) point it at an alternate file, and "" disables the load entirely. JSON values map to setting types as expected: strings to StringValue/PreferenceOptionValue/VisibilityValue/DurationValue (e.g. "24h" parsed by time.ParseDuration), booleans to BooleanValue, numbers to IntegerValue, and string arrays to StringListValue. The file is validated against the registered setting definitions at load time so unknown keys and value/type mismatches fail startup loudly rather than producing surprising defaults at first read. When HuJSON support is linked into the build (default; opt out with ts_omit_hujsonconf), the file may use HuJSON (comments, trailing commas). With ts_omit_hujsonconf it must be pure standard JSON. This mirrors the pattern used by ipn/conffile. On Windows the JSON file and the existing HKLM registry store both register at DeviceScope. rsop merges later-registered same-scope sources over earlier ones, so per-key values in the file override the registry while keys absent from the file fall back to the registry. The loader is registered via a feature.Hook from a file gated by !ts_omit_syspolicy, and called from main after flag parsing. tsnet still does not depend on the root syspolicy package, so embedders don't pick this up implicitly. Fixes #20305 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: Ie6326461c14efb226979ac162998a9c6373ce493
We can use them for traffic until they are actually removed from the table. Updates tailscale/corp#43180 Co-authored-by: Fran Bull <fran@tailscale.com> Co-authored-by: Michael Ben-Ami <mzb@tailscale.com> Signed-off-by: Fran Bull <fran@tailscale.com> Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
Conn25 hands out dummy IP addresses for use in the connector flow from limited address pools. When the addresses are no longer in use we expire the corresponding entry from our table of address mappings and return the addresses to their pools for reuse. We currently expire addresses after the DNS TTL for the DNS response that caused the mappings to be created. Stop expiring mappings when there are active packet flows for the addresses in the mappings. Fixes tailscale/corp#43180 Co-authored-by: Fran Bull <fran@tailscale.com> Co-authored-by: Michael Ben-Ami <mzb@tailscale.com> Signed-off-by: Fran Bull <fran@tailscale.com> Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
Adds a CLI subcommand that downloads a signed Tailscale appliance image (Gokrazy archive format, GAF) from pkgs.tailscale.com, constructs a fresh GPT-partitioned disk from it (mbr.img + a synthesized partition table + boot.img + root.img), formats /perm as ext4 in pure Go via go-diskfs, and ejects the disk so a user running on a regular workstation can flash an SD card or homelab VM disk in one command without installing e2fsprogs. On macOS the target disk is auto-discovered via diskutil, skipping the boot disk and anything bigger than 256 GB out of paranoia. On Linux the user passes --disk=/dev/sdX explicitly. Windows is not supported yet and the command returns an error. The GPT layout matches monogok's full-disk layout via the new public github.com/bradfitz/monogok/disklayout package; a drift- guard test inside monogok asserts the two implementations stay byte-identical so OTA updates against monogok-built images keep working. Behind a ts_omit_flashappliance build tag (on by default). Updates #1866 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: Ic1a8cd185e7039edccb7702ab4104544fcb58d29
Add three new helpers to the existing progresstracking package:
- Ticker: spawns a 1 Hz goroutine that calls a report function with
the current value of an atomic counter and a total. Returns a stop
function (safe to call multiple times via sync.OnceFunc) that fires
one final report and blocks until the goroutine exits.
- NewWriter: wraps an io.Writer and calls onProgress at most once per
interval with the cumulative byte count.
- CountingWriter: an io.Writer that atomically counts bytes written,
for use with Ticker.
These will be used by the appliance flash and OTA update code in
subsequent commits.
Updates #1866
Change-Id: If353cea6506f5351b6fb19bfdb7bc9b78fe7855e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We borked this in 30a89ad and started including skipped extensions (e.g., conn25 when TAILSCALE_USE_WIP_CODE != 1) in the list of active ones. This doesn't have any impact other than on logging, though. Updates #cleanup Signed-off-by: Nick Khyl <nickk@tailscale.com>
Update ts-gokrazy to b83088f which includes:
- Skip hardware watchdog when nowatchdog is on kernel cmdline
- gokrazy.log_to_serial=1 tees service logs to /dev/console
- Fix /etc/resolv.conf symlink (point at /tmp/resolv.conf where
userspace DHCP writes, not /proc/net/pnp which is always empty)
All these things are more emulating a Raspberry Pi in qemu when doing
local development of the appliance image.
Updates #1866
Change-Id: Iba7847e5deb237b1e485b74a4126e31fd118333a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Adds gokrazy/gafpush and a 'make tsapp-push-pi PI=<ip>' Makefile target for pushing a freshly-built GAF to a running appliance over the network. See the gokrazy/gafpush package doc for details. Updates #1866 Change-Id: Id7a0bad712fcf2eddae593f71d5feacee05c5234 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates #20166 Signed-off-by: Adriano Sela Aviles <adriano@tailscale.com>
Adds a Linux-only framebuffer status display (cmd/fbstatus) that draws
to /dev/fb0 on the Tailscale gokrazy appliance. It shows:
- the Tailscale logo
- the current tailscaled state (starting, needs login, running)
- a QR code with the login URL when enrollment is needed (triggers
StartLoginInteractive automatically so the URL appears without
user action)
- the LAN IP or "Waiting for DHCP (MAC)" pinned at the bottom-left
- Tailscale IPs once connected
VT switching: Ctrl-Alt-F2 drops to a busybox text shell on VT2 (for
debugging with a USB keyboard), Ctrl-Alt-F1 returns to the GUI.
Rendering pauses while the text VT is active.
On boot, fbstatus pokes the gokrazy unix socket API to restart the
breakglass SSH service (which uses DontStartOnBoot by default). It
waits until DHCP assigns an IP so breakglass binds to the LAN address
rather than just localhost.
Included in the tsapp-pi.arm64 gokrazy build by default.
Updates #1866
Change-Id: Ifdce4ad8e8c2e1005c840f579e637974a0a266d3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Several improvements to the gokrazy appliance build and flash workflow:
gokrazy/build.go:
- Round Pi image size up to a power of 2 (QEMU raspi3b requires it)
- Use monogok's mkfs.Perm for the /perm ext4 partition (pure Go,
cross-platform, no e2fsprogs dependency)
gokrazy/mkfs:
- Accept optional PermFile entries to include in the freshly-created
ext4 filesystem (used for breakglass authorized_keys)
- Use progresstracking.Ticker for flush progress reporting
gokrazy/tsapp*/config.json:
- Point breakglass at /perm/breakglass.authorized_keys (not ec2)
- Fix Pi SerialConsole to serial0,115200 (not ttyS0)
cmd/tailscale/cli/configure-flash-appliance.go:
- Add --add-ssh-authorized-keys flag to write an authorized_keys
file into /perm during flash (for breakglass SSH access)
- Use progresstracking.CountingWriter + Ticker for write progress
Makefile:
- tsapp-build-and-flash-pi: auto-include ~/.ssh/id_ed25519.pub
- tsapp-qemu-pi: use virt machine + UEFI + ramfb + e1000 (working
network + framebuffer), with DTB watchdog patch and
gokrazy.log_to_serial for debugging
- Auto-detect UEFI firmware path across Debian/Homebrew/Fedora
Updates #1866
Change-Id: Ifa97ad34c509a81e1637d9bce12a788037dfe5ec
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Allow packets with ICMPv4 or ICMPv6 proto to use the flow table and get NATted. Fixes tailscale/corp#40123 Signed-off-by: Fran Bull <fran@tailscale.com>
The macOS tailscaled DNS configurator only wrote /etc/resolver files, which can express split DNS but not a primary resolver. Teach it to configure a global resolver through the SystemConfiguration dynamic store using scutil when OSConfig has nameservers and no match domains. Let non-sandboxed macOS tailscaled follow Linux split DNS behavior when its OS configurator reports split DNS support. This avoids synthesizing an upstream default route from the machine's base DNS when the netmap did not provide one. Keep iOS and sandboxed macOS app builds on the existing Apple base-config path because those use NetworkExtension DNS settings rather than tailscaled's /etc/resolver configurator. Add tests for switching between split and global DNS, including cleanup of stale Tailscale-managed resolver files, removal of the dynamic-store global DNS key, and preservation of the sandboxed macOS behavior. RELNOTE: tailscaled on macOS now supports configuring global DNS resolvers. Updates #1338 Change-Id: I9b2b61f89750a5529fc0add1cd37b1b9a355db12 Signed-off-by: Maisem Ali <maisem@bold.dev>
…entFunc (#20606) Implements a way to send TSMPDiscoAdverts based on a trigger from wireguard-go when a rekey happens. This lets us distribute disco keys consistently, but also sets us up for a minimal message that can be distributed to other clients. A benchmark is implemented to make it easier to keep the call cheap and to avoid locking up anything in wireguard-go. Updates #20081 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
The suggest-exit-node LocalAPI response omits the Location field when the suggested exit node has no location, such as a regular tailnet exit node. Building the exit node menu called CountryCode and City on the invalid view unconditionally, crashing the app on startup. The crash was introduced in aa21b0c (#19627), which added those calls. Add an integration test that starts the systray app against a private dbus session bus, a fake StatusNotifierWatcher, and a fake LocalAPI serving such a suggestion, then verifies the StatusNotifierItem is registered and the initial menu is built. On Linux the systray is pure dbus (StatusNotifierItem and dbusmenu), so no X server or desktop environment is needed and the test runs in existing CI. Fixes #20678 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: I262ae0f724cb7c41aa0f531fcbded967e5bee432
…line (#20552) Previously the acceptEnv variables forwarded to the incubator child were JSON-encoded onto its command line (--encoded-env), so their values were visible in /proc/<pid>/cmdline to any other local user and were logged in the session-start argv (locally and to log.tailscale.com except where --no-logs-no-support was specified). This change now carries those variables through an os.Pipe file descriptor as a json encoded payload. Added end-to-end testing helps validate secrets reach the session but are not in flags or logged. Fixes tailscale/corp#44903 Change-Id: I5b137b20e9c06feec6b70aaf4e6925e6db74017e Signed-off-by: Mike Jensen <mikej@tailscale.com> Co-authored-by: Mike Jensen <mikej@tailscale.com>
Removing this check installs conn25 instance-level hooks whenever the feature is built in. init-level hooks were always installed, but used this guard to exit early. Now all hooks, both instance-level and init-level rely on netmap configuration (populated tailscale.com/app-connectors-experimental node attribute, with non-empty apps) to not exit early. The conn25-shutoff feature flag tells control not to send that node attribute. Fixes tailscale/corp#39033 Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
This function used to have the suffix LockedOnEntry, but no longer has that since #17804. Updates #cleanup Signed-off-by: Naman Sood <mail@nsood.in>
Company policy requires that all cherry-picks onto release branches be made with "git cherry-pick -x" so the commit message records which commit it came from, but nothing enforced that. Add a GitHub Actions check that requires every commit in a PR targeting release-branch/* to have a "(cherry picked from commit ...)" line referencing a commit that's an ancestor of main. PRs that intentionally aren't cherry-picks (version bumps, release-only fixes) can be exempted with the "not-a-cherry-pick" label. Updates tailscale/corp#45854 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: If463d6ecaefd855594d345c733606b411b6fd387
The zstd Encoder and Decoder types use channels internally, created
when the coder is constructed. A coder constructed by a goroutine
inside a testing/synctest bubble therefore owns bubble-associated
channels, and if it lands in zstdframe's process-wide pools and is
later reused outside that bubble, the Go runtime kills the process:
fatal error: receive on synctest channel from outside bubble
This has been crashing test binaries that mix synctest-based tests
with regular tests exercising zstd compression in parallel, taking
out every other test in the package with it.
Add testenv.InSynctestBubble and use it in zstdframe to construct a
fresh coder per call within a bubble instead of using the pools.
Pooling behavior outside of bubbles (including in benchmarks) is
unchanged.
As of Go 1.26 there is no public API to query bubble membership, so
InSynctestBubble looks for the "synctest bubble N" annotation that
the runtime renders in the current goroutine's runtime.Stack header.
That annotation is not covered by the Go compatibility promise, so
tests fail loudly (in util/testenv directly, and in util/zstdframe by
reintroducing the pooled-coder crash) if a future Go release changes
it. The check costs ~2us and runs only in test binaries, detected by
an uncached flag.Lookup("test.v") rather than testenv.InTest: this
path is reachable from package init functions (before testing has
registered its flags), where InTest would permanently latch a false
result into its cache, breaking later InTest and AssertInTest calls.
Fixes tailscale/corp#45861
Change-Id: I7d89e2d0de51e30098ceda25c12d27918acc46e8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
On switching from one tailnet with Connectors 2025 enabled to another, clear the address assignments and flow tables from the previous tailnet. They will not be useful in the new one (since the tailnet configuration and nodes are different), and could blackhole traffic if both tailnets happen to have a connector for the same domain. Fixes tailscale/corp#45619. Signed-off-by: Naman Sood <mail@nsood.in>
This patch extracts the JSON handling for the `tailscale lock` subcommand from the jsonoutput package into its own tslockjsonv1 package. Updates #17613 Signed-off-by: Simon Law <sfllaw@tailscale.com>
This patch extracts the handling of the TKA types for the `tailscale lock` subcommand into its own tka.go file. Updates #17613 Signed-off-by: Simon Law <sfllaw@tailscale.com>
…lscale lock` This patch exports the structs used to unmarshal the JSON output of the `tailscale lock` subcommand. Updates #17613 Change-Id: I615723ff9dbc631e452dbf6bbdeab7b97e96dbb3 Signed-off-by: Simon Law <sfllaw@tailscale.com>
…ale lock` This patch extracts the functions used to marshal the JSON output of the `tailscale lock` subcommand. Updates #17613 Signed-off-by: Simon Law <sfllaw@tailscale.com>
This patch renames the functions in feature/tailnetlock/tstestjsonv1 to remove stuttering. It also adds doc comments. Updates #17613 Signed-off-by: Simon Law <sfllaw@tailscale.com>
…erters This patch pulls the printing and JSON-encoding out of feature/tailnetlock/tslockjsonv1 into their callers, so that this package only handles type conversions. In cmd/tailscale/cli/tailnet-lock.go, it extracts the printTailnetLockStatus function from runTailnetLockStatus to mirror printTailnetLockLog and runTailnetLockLog. Updates #17613 Signed-off-by: Simon Law <sfllaw@tailscale.com>
This patch adds examples of unmarshalling tslockjsonv1.LogResponse and tslockjsonv1.StatusResponse to the documentation. Updates #17613 Signed-off-by: Simon Law <sfllaw@tailscale.com>
Updates #17613 Signed-off-by: Simon Law <sfllaw@tailscale.com>
Updates #20590 Signed-off-by: Jordan Whited <jordan@tailscale.com>
Updates tailscale/corp#45901 Signed-off-by: Adriano Sela Aviles <adriano@tailscale.com>
Point the TS_GO_NEXT=1 toolchain at the tailscale.go1.27 branch so we can start testing Go 1.27 ahead of its release. Updates #20220 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: I7947f1e79b713ff84e0418aef4ed3b17f7fbdbd5
PeerRelay replicas got a single-use auth key minted on config Secret creation and never again, so a replica that lost its login (device deleted, state Secret lost, key expiry) could never re-auth despite containerboot writing the reissue_authkey signal. Port the shouldReissueAuthKey pattern already used by ProxyGroup and Recorder: track in-flight reissues per replica, rate-limit re-issuance per PeerRelay, and delete the stale device before minting a new key. Updates #20544 Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Go 1.27 requires this new v0.8.0-rc.1. But staticcheck 0.8's SA4023 gets stricter and points out that modifiedExternallyError and handleListenersAccept always return non-nil errors, and that MonitorHealth's callers don't need a separate nil check before errors.Is. Simplify all three call sites; no behavior change. But then a handful of other places that SA4023 is angry about are wrong (because it's not considering build tags) and can't be addressed by ignore directives (again not considering build tags), so we just disable SA4023 for now. Updates #20220 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: I2fefe3b986b5798c2e01624a0e9820839d21a569
…c versions
The check strips the rc suffix from the installed toolchain's minor
version (VERSION file, e.g. "go1.27rc2" becomes 27) but not from
go.mod's go directive ("1.27rc2" stays 27rc2). The string comparison
27 -lt 27rc2 is then true, so the wrapper considered an up-to-date rc
toolchain stale and tried to delete it while its go.exe was running,
failing with access denied and breaking the gocross build on Windows.
Strip the rc suffix from both sides.
Updates #20220
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: Ifa74cdfc4f9095133b96579de2f804c74cd9aeab
PR #20388 (commit ca9f697) bumped k8s.io/* from v0.34 to v0.35 as a transitive effect of pulling in helm v3.21 (for containerd CVE fixes). The old controller-runtime v0.19.4 is aligned with k8s 1.31 APIs and regresses at runtime against v0.35 client-go (informer reflectors stall on Watch responses), leaving the operator unable to reconcile. v0.23.3 is the release aligned with k8s.io/* v0.35 / Kubernetes 1.35. The operator uses a narrow slice of controller-runtime (manager + builder + client + reconcile + handler + source), so this bump is a lift-and-shift: no reconciler wiring changes needed. Test scaffolding fix: controller-runtime v0.20+ populates TypeMeta (Kind/APIVersion) on objects returned by the fake client. The shared expectEqual helper now strips TypeMeta before diffing so existing tests continue to work without needing every 'want' object updated. Tested: deployed to live clusters across Kubernetes 1.33, 1.34, 1.35, and 1.36 (identical build per cluster). Verified the operator starts and reconciles cleanly on all versions with no RBAC/forbidden errors, CRDs establish and enforce validation, and the field indexers resolve correctly under annotation churn (no stale-index misrouting). Exercised the Service, ProxyClass, Connector, egress (simple + ProxyGroup, incl. the EndpointSlice reconciler), and HA ingress-for-pg reconcilers. Confirmed informer/watch recovery after an API server restart forces a re-list/re-watch (the exact regression this bump fixes). Updates tailscale/corp#44898 Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Go 1.27's go mod tidy merges and reorganizes the require blocks once the go directive in go.mod is 1.27 or newer. Land that mechanical reorganization now (generated with a temporary 1.27 directive, with the directive then restored) so the eventual toolchain switch doesn't carry a 300+ line go.mod diff. Both Go 1.26's and Go 1.27's go mod tidy leave the reorganized file unchanged, and go.sum and the selected module versions are identical, so this is purely cosmetic. Updates #20220 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: If7af51ca71ec30026034cf736f992e731c0e0531
Commit 33042fb (go.mod: bump sigs.k8s.io/controller-runtime to v0.23.3) was based on a stale tree and accidentally reverted the staticcheck bump from 7eeb624 back to v0.7.0. That version's IR builder panics on the Go 1.27 standard library (unexpected expr: *ast.KeyValueExpr), breaking staticcheck CI on the Go 1.27 test branch. Everything else in that commit was intentional k8s ecosystem upgrades; staticcheck was the only collateral revert. Updates #20220 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: I763a3dcc29e592adcf6979c80d6e720b02c0bb09
We'll need this in corp at least, which means we need this here. Updates #20220 Change-Id: I5dbf93f2b9ce05658193fc8ba61eb61185637521 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
…tity
The ts_omit_unixsocketidentity variant of GetConnIdentity never
performs the *net.UnixConn type assertion, so ConnIdentity.isUnixSock
stays false. ipnserver's Permissions only grants local API access to
unix socket connections, so with this build tag every local API request
is denied read and write access ("status access denied") and the CLI
cannot talk to the daemon at all in --extra-small/--min builds.
Mirror the type assertion from the peercred variant so the omitted
identity build behaves as intended (everyone is an admin when unix
socket identities are compiled out).
Signed-off-by: loowr <loowr@proton.me>
LocalBackend.Shutdown waits for the ACME refresh loop and active SSH sessions. Both can be blocked acquiring LocalBackend.mu, so waiting while holding that mutex deadlocks shutdown. Detach the SSH server under the mutex, then stop both subsystems after releasing it. Prevent their work from restarting once shutdown begins, and serialize repeated Shutdown calls with sync.Once. Add regression tests that verify subsystem shutdown runs without LocalBackend.mu held. Updates tailscale/corp#45964 Change-Id: I37ead4f26fbfb5703a83882668d98a8862ba7d67 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
No description provided.