Go 1.27 enables GOEXPERIMENT=jsonv2 by default: encoding/json is now
backed by the json/v2 machinery, and github.com/go-json-experiment/json
compiles as a thin alias of the standard library's encoding/json/v2.
Several tag options and behaviors we relied on did not make the cut for
the final Go 1.27 API, breaking tailscaled at runtime and four packages'
tests. This change adapts to the final API while keeping the wire format
byte-for-byte identical on all Go versions.
First, the `format` tag option was demoted to experimental. Its mere
presence in a struct tag now makes marshaling and unmarshaling fail at
runtime. tailcfg.SSHAction.SessionDuration had `format:nano` (added in
a2dc517d7 to pin the v1 representation), so on Go 1.27 any netmap
containing an SSH policy failed to decode, breaking every PollNetMap.
Remove the option here and in net/speedtest; time.Duration still
marshals as int64 nanoseconds under encoding/json on all Go versions
(Go 1.27's v1 mode sets FormatDurationAsNano by default), so old
clients and servers are unaffected. Add a regression test locking in
the exact wire format.
Consequently, invert the cmd/vet jsontags rule: it previously required
an explicit `format` tag on time.Duration fields, which is now exactly
wrong. It now rejects any `format` tag option, which would have caught
this bug in CI.
Second, the `inline` tag option was renamed to `embed`. The standard
library silently ignores `inline`, while the pinned go-json-experiment
module (used on Go 1.26) only knows `inline`. Specify both options in
types/prefs and logtail; each implementation ignores the option it does
not know, producing identical output. Drop `inline` once we require
Go 1.27.
Third, encoding/json (v1) now dispatches to MarshalJSONTo and
UnmarshalJSONFrom methods and its v1 options flow into nested
jsonv2.MarshalEncode calls. Types whose v1 methods deliberately
routed through jsonv2 for v2 semantics (types/opt.Value, the
types/prefs preference types) would silently change wire format
(e.g. nil slices becoming null). Pin jsonv2.DefaultOptionsV2 in
their jsonv2 methods so the representation is the same regardless
of the entry point.
Finally, json.Marshal costs one more allocation under Go 1.27,
tripping the types/logger.AsJSON alloc test. Switch its fmt.Formatter
to jsonv2.MarshalWrite with explicit v1 options, which writes directly
to the fmt.State: one allocation on both toolchains with unchanged
output. Depaware files pick up the go-json-experiment/json/v1 options
shim as a new dependency of types/logger.
With this change, go test ./... passes with both Go 1.26.5 and
go1.27rc2.
Updates #20220
Fixes #20528
Fixes #20254
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I694c7d57fd81e55a579c579e9be10032bca569d4
315 lines
30 KiB
Plaintext
315 lines
30 KiB
Plaintext
tailscale.com/cmd/stund dependencies: (generated by github.com/tailscale/depaware)
|
|
|
|
💣 crypto/internal/entropy/v1.0.0 from crypto/internal/fips140/drbg
|
|
github.com/beorn7/perks/quantile from github.com/prometheus/client_golang/prometheus
|
|
💣 github.com/cespare/xxhash/v2 from github.com/prometheus/client_golang/prometheus
|
|
github.com/go-json-experiment/json from tailscale.com/types/opt+
|
|
github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
|
|
github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
|
|
github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
|
|
github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+
|
|
github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+
|
|
github.com/go-json-experiment/json/v1 from tailscale.com/types/logger
|
|
github.com/munnerz/goautoneg from github.com/prometheus/common/expfmt
|
|
💣 github.com/prometheus/client_golang/prometheus from tailscale.com/tsweb/promvarz
|
|
github.com/prometheus/client_golang/prometheus/internal from github.com/prometheus/client_golang/prometheus
|
|
github.com/prometheus/client_model/go from github.com/prometheus/client_golang/prometheus+
|
|
github.com/prometheus/common/expfmt from github.com/prometheus/client_golang/prometheus+
|
|
github.com/prometheus/common/model from github.com/prometheus/client_golang/prometheus+
|
|
L github.com/prometheus/procfs from github.com/prometheus/client_golang/prometheus
|
|
L github.com/prometheus/procfs/internal/fs from github.com/prometheus/procfs
|
|
L github.com/prometheus/procfs/internal/util from github.com/prometheus/procfs
|
|
💣 go4.org/mem from tailscale.com/metrics+
|
|
go4.org/netipx from tailscale.com/net/tsaddr
|
|
google.golang.org/protobuf/encoding/protodelim from github.com/prometheus/common/expfmt
|
|
google.golang.org/protobuf/encoding/prototext from github.com/prometheus/common/expfmt+
|
|
google.golang.org/protobuf/encoding/protowire from google.golang.org/protobuf/encoding/protodelim+
|
|
google.golang.org/protobuf/internal/descfmt from google.golang.org/protobuf/internal/filedesc
|
|
google.golang.org/protobuf/internal/descopts from google.golang.org/protobuf/internal/filedesc+
|
|
google.golang.org/protobuf/internal/detrand from google.golang.org/protobuf/internal/descfmt+
|
|
google.golang.org/protobuf/internal/editiondefaults from google.golang.org/protobuf/internal/filedesc
|
|
google.golang.org/protobuf/internal/encoding/defval from google.golang.org/protobuf/internal/encoding/tag+
|
|
google.golang.org/protobuf/internal/encoding/messageset from google.golang.org/protobuf/encoding/prototext+
|
|
google.golang.org/protobuf/internal/encoding/tag from google.golang.org/protobuf/internal/impl
|
|
google.golang.org/protobuf/internal/encoding/text from google.golang.org/protobuf/encoding/prototext+
|
|
google.golang.org/protobuf/internal/errors from google.golang.org/protobuf/encoding/prototext+
|
|
google.golang.org/protobuf/internal/filedesc from google.golang.org/protobuf/internal/encoding/tag+
|
|
google.golang.org/protobuf/internal/filetype from google.golang.org/protobuf/runtime/protoimpl
|
|
google.golang.org/protobuf/internal/flags from google.golang.org/protobuf/encoding/prototext+
|
|
google.golang.org/protobuf/internal/genid from google.golang.org/protobuf/encoding/prototext+
|
|
💣 google.golang.org/protobuf/internal/impl from google.golang.org/protobuf/internal/filetype+
|
|
google.golang.org/protobuf/internal/order from google.golang.org/protobuf/encoding/prototext+
|
|
google.golang.org/protobuf/internal/pragma from google.golang.org/protobuf/encoding/prototext+
|
|
💣 google.golang.org/protobuf/internal/protolazy from google.golang.org/protobuf/internal/impl+
|
|
google.golang.org/protobuf/internal/set from google.golang.org/protobuf/encoding/prototext
|
|
💣 google.golang.org/protobuf/internal/strs from google.golang.org/protobuf/encoding/prototext+
|
|
google.golang.org/protobuf/internal/version from google.golang.org/protobuf/runtime/protoimpl
|
|
google.golang.org/protobuf/proto from github.com/prometheus/client_golang/prometheus+
|
|
💣 google.golang.org/protobuf/reflect/protoreflect from github.com/prometheus/client_model/go+
|
|
google.golang.org/protobuf/reflect/protoregistry from google.golang.org/protobuf/encoding/prototext+
|
|
google.golang.org/protobuf/runtime/protoiface from google.golang.org/protobuf/internal/impl+
|
|
google.golang.org/protobuf/runtime/protoimpl from github.com/prometheus/client_model/go+
|
|
💣 google.golang.org/protobuf/types/known/timestamppb from github.com/prometheus/client_golang/prometheus+
|
|
tailscale.com from tailscale.com/version
|
|
tailscale.com/envknob from tailscale.com/tsweb+
|
|
tailscale.com/feature from tailscale.com/tsweb
|
|
tailscale.com/feature/buildfeatures from tailscale.com/feature+
|
|
tailscale.com/kube/kubetypes from tailscale.com/envknob
|
|
tailscale.com/metrics from tailscale.com/net/stunserver+
|
|
tailscale.com/net/netaddr from tailscale.com/net/tsaddr
|
|
tailscale.com/net/stun from tailscale.com/net/stunserver
|
|
tailscale.com/net/stunserver from tailscale.com/cmd/stund
|
|
tailscale.com/net/tsaddr from tailscale.com/tsweb
|
|
tailscale.com/syncs from tailscale.com/metrics+
|
|
tailscale.com/tailcfg from tailscale.com/version+
|
|
tailscale.com/tstime from tailscale.com/tsweb
|
|
tailscale.com/tsweb from tailscale.com/cmd/stund+
|
|
tailscale.com/tsweb/promvarz from tailscale.com/cmd/stund
|
|
tailscale.com/tsweb/varz from tailscale.com/tsweb+
|
|
tailscale.com/types/dnstype from tailscale.com/tailcfg
|
|
tailscale.com/types/ipproto from tailscale.com/tailcfg
|
|
tailscale.com/types/key from tailscale.com/tailcfg+
|
|
tailscale.com/types/lazy from tailscale.com/version+
|
|
tailscale.com/types/logger from tailscale.com/tsweb+
|
|
tailscale.com/types/opt from tailscale.com/envknob+
|
|
tailscale.com/types/persist from tailscale.com/feature
|
|
tailscale.com/types/result from tailscale.com/util/lineiter
|
|
tailscale.com/types/structs from tailscale.com/tailcfg+
|
|
tailscale.com/types/tkatype from tailscale.com/tailcfg+
|
|
tailscale.com/types/views from tailscale.com/net/tsaddr+
|
|
tailscale.com/util/bufiox from tailscale.com/types/key
|
|
tailscale.com/util/ctxkey from tailscale.com/tsweb+
|
|
L 💣 tailscale.com/util/dirwalk from tailscale.com/metrics
|
|
tailscale.com/util/dnsname from tailscale.com/tailcfg
|
|
tailscale.com/util/lineiter from tailscale.com/version/distro
|
|
tailscale.com/util/mak from tailscale.com/syncs+
|
|
tailscale.com/util/nocasemaps from tailscale.com/types/ipproto
|
|
tailscale.com/util/rands from tailscale.com/tsweb
|
|
tailscale.com/util/set from tailscale.com/types/key
|
|
tailscale.com/util/slicesx from tailscale.com/tailcfg
|
|
tailscale.com/util/testenv from tailscale.com/types/logger+
|
|
tailscale.com/util/vizerror from tailscale.com/tailcfg+
|
|
tailscale.com/version from tailscale.com/envknob+
|
|
tailscale.com/version/distro from tailscale.com/envknob
|
|
golang.org/x/crypto/blake2b from golang.org/x/crypto/nacl/box
|
|
golang.org/x/crypto/curve25519 from golang.org/x/crypto/nacl/box+
|
|
golang.org/x/crypto/internal/alias from golang.org/x/crypto/nacl/secretbox
|
|
golang.org/x/crypto/internal/poly1305 from golang.org/x/crypto/nacl/secretbox
|
|
golang.org/x/crypto/nacl/box from tailscale.com/types/key
|
|
golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box
|
|
golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+
|
|
golang.org/x/exp/constraints from tailscale.com/tsweb/varz+
|
|
golang.org/x/sys/cpu from golang.org/x/crypto/blake2b+
|
|
LD golang.org/x/sys/unix from github.com/prometheus/procfs+
|
|
W golang.org/x/sys/windows from github.com/prometheus/client_golang/prometheus
|
|
vendor/golang.org/x/crypto/chacha20 from vendor/golang.org/x/crypto/chacha20poly1305
|
|
vendor/golang.org/x/crypto/chacha20poly1305 from crypto/hpke+
|
|
vendor/golang.org/x/crypto/cryptobyte from crypto/ecdsa+
|
|
vendor/golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+
|
|
vendor/golang.org/x/crypto/internal/alias from vendor/golang.org/x/crypto/chacha20+
|
|
vendor/golang.org/x/crypto/internal/poly1305 from vendor/golang.org/x/crypto/chacha20poly1305
|
|
vendor/golang.org/x/net/dns/dnsmessage from net
|
|
vendor/golang.org/x/net/http/httpguts from net/http+
|
|
vendor/golang.org/x/net/http/httpproxy from net/http
|
|
vendor/golang.org/x/net/http2/hpack from net/http+
|
|
vendor/golang.org/x/net/idna from net/http+
|
|
vendor/golang.org/x/sys/cpu from vendor/golang.org/x/crypto/chacha20poly1305
|
|
vendor/golang.org/x/text/secure/bidirule from vendor/golang.org/x/net/idna
|
|
vendor/golang.org/x/text/transform from vendor/golang.org/x/text/secure/bidirule+
|
|
vendor/golang.org/x/text/unicode/bidi from vendor/golang.org/x/net/idna+
|
|
vendor/golang.org/x/text/unicode/norm from vendor/golang.org/x/net/idna
|
|
bufio from compress/flate+
|
|
bytes from bufio+
|
|
cmp from slices+
|
|
compress/flate from compress/gzip+
|
|
compress/gzip from google.golang.org/protobuf/internal/impl+
|
|
container/list from crypto/tls+
|
|
context from crypto/tls+
|
|
crypto from crypto/ecdh+
|
|
crypto/aes from crypto/tls+
|
|
crypto/cipher from crypto/aes+
|
|
crypto/des from crypto/tls+
|
|
crypto/dsa from crypto/x509
|
|
crypto/ecdh from crypto/ecdsa+
|
|
crypto/ecdsa from crypto/tls+
|
|
crypto/ed25519 from crypto/tls+
|
|
crypto/elliptic from crypto/ecdsa+
|
|
crypto/fips140 from crypto/tls/internal/fips140tls+
|
|
crypto/hkdf from crypto/hpke+
|
|
crypto/hmac from crypto/tls
|
|
crypto/hpke from crypto/tls
|
|
crypto/internal/boring from crypto/aes+
|
|
crypto/internal/boring/bbig from crypto/ecdsa+
|
|
crypto/internal/boring/sig from crypto/internal/boring
|
|
crypto/internal/constanttime from crypto/internal/fips140/edwards25519+
|
|
crypto/internal/fips140 from crypto/fips140+
|
|
crypto/internal/fips140/aes from crypto/aes+
|
|
crypto/internal/fips140/aes/gcm from crypto/cipher+
|
|
crypto/internal/fips140/alias from crypto/cipher+
|
|
crypto/internal/fips140/bigmod from crypto/internal/fips140/ecdsa+
|
|
crypto/internal/fips140/check from crypto/fips140+
|
|
crypto/internal/fips140/drbg from crypto/hpke+
|
|
crypto/internal/fips140/ecdh from crypto/ecdh
|
|
crypto/internal/fips140/ecdsa from crypto/ecdsa
|
|
crypto/internal/fips140/ed25519 from crypto/ed25519
|
|
crypto/internal/fips140/edwards25519 from crypto/internal/fips140/ed25519
|
|
crypto/internal/fips140/edwards25519/field from crypto/ecdh+
|
|
crypto/internal/fips140/hkdf from crypto/hkdf+
|
|
crypto/internal/fips140/hmac from crypto/hmac+
|
|
crypto/internal/fips140/mlkem from crypto/mlkem
|
|
crypto/internal/fips140/nistec from crypto/ecdsa+
|
|
crypto/internal/fips140/nistec/fiat from crypto/internal/fips140/nistec
|
|
crypto/internal/fips140/rsa from crypto/rsa
|
|
crypto/internal/fips140/sha256 from crypto/internal/fips140/check+
|
|
crypto/internal/fips140/sha3 from crypto/internal/fips140/hmac+
|
|
crypto/internal/fips140/sha512 from crypto/internal/fips140/ecdsa+
|
|
crypto/internal/fips140/subtle from crypto/internal/fips140/aes+
|
|
crypto/internal/fips140/tls12 from crypto/tls
|
|
crypto/internal/fips140/tls13 from crypto/tls
|
|
crypto/internal/fips140cache from crypto/ecdsa+
|
|
crypto/internal/fips140deps/byteorder from crypto/internal/fips140/aes+
|
|
crypto/internal/fips140deps/cpu from crypto/internal/fips140/aes+
|
|
crypto/internal/fips140deps/godebug from crypto/internal/fips140+
|
|
crypto/internal/fips140deps/time from crypto/internal/entropy/v1.0.0
|
|
crypto/internal/fips140hash from crypto/ecdsa+
|
|
crypto/internal/fips140only from crypto/cipher+
|
|
crypto/internal/impl from crypto/internal/fips140/aes+
|
|
crypto/internal/rand from crypto/dsa+
|
|
crypto/internal/randutil from crypto/internal/rand
|
|
crypto/internal/sysrand from crypto/internal/fips140/drbg
|
|
crypto/md5 from crypto/tls+
|
|
crypto/mlkem from crypto/hpke+
|
|
crypto/rand from crypto/ed25519+
|
|
crypto/rc4 from crypto/tls
|
|
crypto/rsa from crypto/tls+
|
|
crypto/sha1 from crypto/tls+
|
|
crypto/sha256 from crypto/tls+
|
|
crypto/sha3 from crypto/internal/fips140hash+
|
|
crypto/sha512 from crypto/ecdsa+
|
|
crypto/subtle from crypto/cipher+
|
|
crypto/tls from net/http+
|
|
crypto/tls/internal/fips140tls from crypto/tls
|
|
crypto/x509 from crypto/tls
|
|
D crypto/x509/internal/macos from crypto/x509
|
|
crypto/x509/pkix from crypto/x509
|
|
embed from google.golang.org/protobuf/internal/editiondefaults+
|
|
encoding from encoding/json+
|
|
encoding/asn1 from crypto/x509+
|
|
encoding/base32 from github.com/go-json-experiment/json
|
|
encoding/base64 from encoding/json+
|
|
encoding/binary from compress/gzip+
|
|
encoding/hex from crypto/x509+
|
|
encoding/json from expvar+
|
|
encoding/pem from crypto/tls+
|
|
errors from bufio+
|
|
expvar from github.com/prometheus/client_golang/prometheus+
|
|
flag from tailscale.com/cmd/stund+
|
|
fmt from compress/flate+
|
|
go/token from google.golang.org/protobuf/internal/strs
|
|
hash from crypto+
|
|
hash/crc32 from compress/gzip+
|
|
hash/fnv from google.golang.org/protobuf/internal/detrand
|
|
hash/maphash from go4.org/mem
|
|
html from net/http/pprof+
|
|
internal/abi from crypto/x509/internal/macos+
|
|
internal/asan from internal/runtime/maps+
|
|
internal/bisect from internal/godebug
|
|
internal/bytealg from bytes+
|
|
internal/byteorder from crypto/cipher+
|
|
internal/chacha8rand from math/rand/v2+
|
|
internal/coverage/rtcov from runtime
|
|
internal/cpu from crypto/internal/fips140deps/cpu+
|
|
internal/filepathlite from os+
|
|
internal/fmtsort from fmt
|
|
internal/goarch from crypto/internal/fips140deps/cpu+
|
|
internal/godebug from crypto/ed25519+
|
|
internal/godebugs from internal/godebug+
|
|
internal/goexperiment from net/http/pprof+
|
|
internal/goos from crypto/x509+
|
|
internal/msan from internal/runtime/maps+
|
|
internal/nettrace from net+
|
|
internal/oserror from internal/syscall/windows+
|
|
internal/poll from net+
|
|
internal/profile from net/http/pprof
|
|
internal/profilerecord from runtime+
|
|
internal/race from internal/poll+
|
|
internal/reflectlite from context+
|
|
D internal/routebsd from net
|
|
internal/runtime/atomic from internal/runtime/exithook+
|
|
L internal/runtime/cgroup from runtime
|
|
internal/runtime/exithook from runtime
|
|
internal/runtime/gc from internal/runtime/gc/scan+
|
|
internal/runtime/gc/scan from runtime
|
|
internal/runtime/maps from hash/maphash+
|
|
internal/runtime/math from internal/runtime/maps+
|
|
internal/runtime/pprof/label from runtime+
|
|
internal/runtime/sys from crypto/subtle+
|
|
L internal/runtime/syscall/linux from internal/runtime/cgroup+
|
|
W internal/runtime/syscall/windows from internal/syscall/windows+
|
|
internal/saferio from encoding/asn1
|
|
internal/singleflight from net
|
|
internal/strconv from internal/poll+
|
|
internal/stringslite from embed+
|
|
internal/sync from sync+
|
|
internal/synctest from sync
|
|
internal/syscall/execenv from os
|
|
LD internal/syscall/unix from crypto/internal/sysrand+
|
|
W internal/syscall/windows from crypto/internal/fips140deps/time+
|
|
W internal/syscall/windows/registry from mime+
|
|
W internal/syscall/windows/sysdll from internal/syscall/windows+
|
|
internal/testlog from os
|
|
internal/trace/tracev2 from runtime+
|
|
internal/unsafeheader from internal/reflectlite+
|
|
io from bufio+
|
|
io/fs from crypto/x509+
|
|
iter from maps+
|
|
log from expvar+
|
|
log/internal from log
|
|
maps from tailscale.com/tailcfg+
|
|
math from compress/flate+
|
|
math/big from crypto/dsa+
|
|
math/bits from compress/flate+
|
|
math/rand from math/big+
|
|
math/rand/v2 from crypto/ecdsa+
|
|
mime from github.com/prometheus/common/expfmt+
|
|
mime/multipart from net/http
|
|
mime/quotedprintable from mime/multipart
|
|
net from crypto/tls+
|
|
net/http from expvar+
|
|
net/http/httptrace from net/http+
|
|
net/http/internal from net/http
|
|
net/http/internal/ascii from net/http
|
|
net/http/internal/httpcommon from net/http
|
|
net/http/pprof from tailscale.com/tsweb
|
|
net/netip from go4.org/netipx+
|
|
net/textproto from mime/multipart+
|
|
net/url from crypto/x509+
|
|
os from crypto/internal/sysrand+
|
|
os/signal from tailscale.com/cmd/stund
|
|
path from github.com/prometheus/client_golang/prometheus/internal+
|
|
path/filepath from crypto/x509+
|
|
reflect from encoding/asn1+
|
|
regexp from github.com/prometheus/client_golang/prometheus/internal+
|
|
regexp/syntax from regexp
|
|
runtime from crypto/internal/fips140+
|
|
runtime/debug from github.com/prometheus/client_golang/prometheus+
|
|
runtime/metrics from github.com/prometheus/client_golang/prometheus+
|
|
runtime/pprof from net/http/pprof
|
|
runtime/trace from net/http/pprof
|
|
slices from tailscale.com/metrics+
|
|
sort from compress/flate+
|
|
strconv from compress/flate+
|
|
strings from bufio+
|
|
W structs from internal/syscall/windows
|
|
sync from compress/flate+
|
|
sync/atomic from context+
|
|
syscall from crypto/internal/sysrand+
|
|
text/tabwriter from runtime/pprof
|
|
time from compress/gzip+
|
|
unicode from bytes+
|
|
unicode/utf16 from crypto/x509+
|
|
unicode/utf8 from bufio+
|
|
unique from net/netip
|
|
unsafe from bytes+
|
|
weak from unique+
|