Update
This commit is contained in:
1 parent
3530afb854
commit
6903fcff27
2146 files changed
+112256
-190703
No files matched your search
+30
-15
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package hostinfo answers questions about the host environment that Tailscale is
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/lazy"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/util/cloudenv"
|
||||
"tailscale.com/util/dnsname"
|
||||
"tailscale.com/util/lineiter"
|
||||
@@ -75,13 +74,14 @@ func New() *tailcfg.Hostinfo {
|
||||
|
||||
// non-nil on some platforms
|
||||
var (
|
||||
osVersion func() string
|
||||
packageType func() string
|
||||
distroName func() string
|
||||
distroVersion func() string
|
||||
distroCodeName func() string
|
||||
unameMachine func() string
|
||||
deviceModel func() string
|
||||
osVersion func() string
|
||||
packageType func() string
|
||||
distroName func() string
|
||||
distroVersion func() string
|
||||
distroCodeName func() string
|
||||
unameMachine func() string
|
||||
deviceModel func() string
|
||||
systemdLogindDesktop func() bool
|
||||
)
|
||||
|
||||
func condCall[T any](fn func() T) T {
|
||||
@@ -93,8 +93,8 @@ func condCall[T any](fn func() T) T {
|
||||
}
|
||||
|
||||
var (
|
||||
lazyInContainer = &lazyAtomicValue[opt.Bool]{f: ptr.To(inContainer)}
|
||||
lazyGoArchVar = &lazyAtomicValue[string]{f: ptr.To(goArchVar)}
|
||||
lazyInContainer = &lazyAtomicValue[opt.Bool]{f: new(inContainer)}
|
||||
lazyGoArchVar = &lazyAtomicValue[string]{f: new(goArchVar)}
|
||||
)
|
||||
|
||||
type lazyAtomicValue[T any] struct {
|
||||
@@ -233,6 +233,12 @@ func FirewallMode() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// desktop reports whether the system is running a Linux desktop environment.
|
||||
// The result is undefined for non-Linux systems.
|
||||
// It checks systemd-logind, and then via reading the list of open unix sockets
|
||||
// and seeing if any of them matches names of wayland, x11 or mir.
|
||||
// The detection runs for a minute after starting tailscaled, after that the
|
||||
// value is cached and returned directly from the cache.
|
||||
func desktop() (ret opt.Bool) {
|
||||
if runtime.GOOS != "linux" {
|
||||
return opt.Bool("")
|
||||
@@ -243,10 +249,19 @@ func desktop() (ret opt.Bool) {
|
||||
}
|
||||
|
||||
seenDesktop := false
|
||||
for lr := range lineiter.File("/proc/net/unix") {
|
||||
line, _ := lr.Value()
|
||||
seenDesktop = seenDesktop || mem.Contains(mem.B(line), mem.S(".X11-unix"))
|
||||
seenDesktop = seenDesktop || mem.Contains(mem.B(line), mem.S("/wayland-1"))
|
||||
if systemdLogindDesktop != nil {
|
||||
seenDesktop = systemdLogindDesktop()
|
||||
}
|
||||
if !seenDesktop {
|
||||
for lr := range lineiter.File("/proc/net/unix") {
|
||||
line, _ := lr.Value()
|
||||
if seenDesktop = mem.Contains(mem.B(line), mem.S(".X11-unix")) ||
|
||||
mem.Contains(mem.B(line), mem.S("/wayland-")) ||
|
||||
mem.Contains(mem.B(line), mem.S("mir_socket")) ||
|
||||
mem.Contains(mem.B(line), mem.S("gamescope-")); seenDesktop {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.Set(seenDesktop)
|
||||
|
||||
|
||||
+17
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build darwin
|
||||
@@ -8,14 +8,30 @@ package hostinfo
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func init() {
|
||||
osVersion = lazyOSVersion.Get
|
||||
packageType = packageTypeDarwin
|
||||
}
|
||||
|
||||
var (
|
||||
lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionDarwin)}
|
||||
)
|
||||
|
||||
func packageTypeDarwin() string {
|
||||
// Using tailscaled or IPNExtension?
|
||||
exe, _ := os.Executable()
|
||||
return filepath.Base(exe)
|
||||
}
|
||||
|
||||
// Returns the marketing version (e.g., "15.0.1" or "26.0.0")
|
||||
func osVersionDarwin() string {
|
||||
version, err := unix.Sysctl("kern.osproductversion")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return version
|
||||
}
|
||||
+3
-4
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build freebsd
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"os/exec"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/version/distro"
|
||||
)
|
||||
|
||||
@@ -22,8 +21,8 @@ func init() {
|
||||
}
|
||||
|
||||
var (
|
||||
lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: ptr.To(freebsdVersionMeta)}
|
||||
lazyOSVersion = &lazyAtomicValue[string]{f: ptr.To(osVersionFreeBSD)}
|
||||
lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: new(freebsdVersionMeta)}
|
||||
lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionFreeBSD)}
|
||||
)
|
||||
|
||||
func distroNameFreeBSD() string {
|
||||
|
||||
+103
-8
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build linux && !android
|
||||
@@ -7,11 +7,14 @@ package hostinfo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/util/lineiter"
|
||||
"tailscale.com/version/distro"
|
||||
)
|
||||
@@ -23,11 +26,12 @@ func init() {
|
||||
distroVersion = distroVersionLinux
|
||||
distroCodeName = distroCodeNameLinux
|
||||
deviceModel = deviceModelLinux
|
||||
systemdLogindDesktop = hasLogindDesktop
|
||||
}
|
||||
|
||||
var (
|
||||
lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: ptr.To(linuxVersionMeta)}
|
||||
lazyOSVersion = &lazyAtomicValue[string]{f: ptr.To(osVersionLinux)}
|
||||
lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: new(linuxVersionMeta)}
|
||||
lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionLinux)}
|
||||
)
|
||||
|
||||
type versionMeta struct {
|
||||
@@ -69,7 +73,7 @@ func deviceModelLinux() string {
|
||||
}
|
||||
|
||||
func getQnapQtsVersion(versionInfo string) string {
|
||||
for _, field := range strings.Fields(versionInfo) {
|
||||
for field := range strings.FieldsSeq(versionInfo) {
|
||||
if suffix, ok := strings.CutPrefix(field, "QTSFW_"); ok {
|
||||
return suffix
|
||||
}
|
||||
@@ -111,11 +115,11 @@ func linuxVersionMeta() (meta versionMeta) {
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
eq := bytes.IndexByte(line, '=')
|
||||
if eq == -1 {
|
||||
before, after, ok := bytes.Cut(line, []byte{'='})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
k, v := string(line[:eq]), strings.Trim(string(line[eq+1:]), `"'`)
|
||||
k, v := string(before), strings.Trim(string(after), `"'`)
|
||||
m[k] = v
|
||||
}
|
||||
|
||||
@@ -178,3 +182,94 @@ func packageTypeLinux() string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// hasLogindDesktop calls [systemdLogindFindDesktop] with a 100 millisecond
|
||||
// timeout.
|
||||
func hasLogindDesktop() bool {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancel()
|
||||
runner := &osLogindRunner{ctx: ctx}
|
||||
return systemdLogindFindDesktop(runner)
|
||||
}
|
||||
|
||||
// logindConn is the interface for querying systemd-logind session information.
|
||||
// It exists to be able to swap the backend for testing.
|
||||
type logindRunner interface {
|
||||
// listSessions returns the raw JSON output of
|
||||
// "loginctl list-sessions --json=short", which is a json blob containing
|
||||
// output like: '[{"session":"8"},{"session":"9"}]'.
|
||||
listSessions() ([]byte, error)
|
||||
|
||||
// getSessionType returns the raw output of
|
||||
// "loginctl show-session <id> --property=Type", which is a single line of
|
||||
// the form "Type=<value>".
|
||||
getSessionType(string) (string, error)
|
||||
}
|
||||
|
||||
// osLogindRunner implements [logindRunner] by shelling out to the system logind.
|
||||
type osLogindRunner struct{ ctx context.Context }
|
||||
|
||||
// listSessions implements [logindRunner] using os calls.
|
||||
func (r *osLogindRunner) listSessions() ([]byte, error) {
|
||||
path, err := exec.LookPath("loginctl")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := exec.CommandContext(r.ctx, path, "list-sessions", "--json=short")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// getSessionType implements [logindRunner] using os calls.
|
||||
func (r *osLogindRunner) getSessionType(session string) (string, error) {
|
||||
path, err := exec.LookPath("loginctl")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cmd := exec.CommandContext(r.ctx,
|
||||
path, "show-session", session, "--property=Type", "--value")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(output), nil
|
||||
}
|
||||
|
||||
// systemdLogindFindDesktop reports whether any active logind session has a
|
||||
// graphical desktop type (x11, wayland, or mir). On an error or with no types
|
||||
// matching the list above, it returns false.
|
||||
func systemdLogindFindDesktop(logind logindRunner) bool {
|
||||
sessionJSON, err := logind.listSessions()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
type session struct {
|
||||
Session string `json:"session"`
|
||||
}
|
||||
|
||||
var sessions []session
|
||||
err = json.Unmarshal(sessionJSON, &sessions)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, sess := range sessions {
|
||||
typeString, err := logind.getSessionType(sess.Session)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
switch strings.ToLower(strings.TrimSpace(typeString)) {
|
||||
case "wayland", "x11", "mir":
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package hostinfo
|
||||
|
||||
+2
-3
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build linux || freebsd || openbsd || darwin
|
||||
@@ -9,14 +9,13 @@ import (
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func init() {
|
||||
unameMachine = lazyUnameMachine.Get
|
||||
}
|
||||
|
||||
var lazyUnameMachine = &lazyAtomicValue[string]{f: ptr.To(unameMachineUnix)}
|
||||
var lazyUnameMachine = &lazyAtomicValue[string]{f: new(unameMachineUnix)}
|
||||
|
||||
func unameMachineUnix() string {
|
||||
switch runtime.GOOS {
|
||||
|
||||
+4
-5
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package hostinfo
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/util/winutil"
|
||||
"tailscale.com/util/winutil/winenv"
|
||||
)
|
||||
@@ -23,9 +22,9 @@ func init() {
|
||||
}
|
||||
|
||||
var (
|
||||
lazyDistroName = &lazyAtomicValue[string]{f: ptr.To(distroNameWindows)}
|
||||
lazyOSVersion = &lazyAtomicValue[string]{f: ptr.To(osVersionWindows)}
|
||||
lazyPackageType = &lazyAtomicValue[string]{f: ptr.To(packageTypeWindows)}
|
||||
lazyDistroName = &lazyAtomicValue[string]{f: new(distroNameWindows)}
|
||||
lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionWindows)}
|
||||
lazyPackageType = &lazyAtomicValue[string]{f: new(packageTypeWindows)}
|
||||
)
|
||||
|
||||
func distroNameWindows() string {
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build linux && ts_appliance
|
||||
|
||||
package hostinfo
|
||||
|
||||
func init() {
|
||||
linuxBuildTagPackageType = "tsapp"
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build linux && ts_package_container
|
||||
|
||||
Reference in new issue
Block a user