mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
version: undo previous "optimization", do more work lazily
Commit 59c254579ea63c669ffb3b5031e51288422c5194 moved a lot of work from functions that could be eliminated at compile time (because tests against runtime.GOOS are compile-time constant), into code that must always run before main(). So, revert that, and instead optimize the package only by moving the remaining string processing code behind sync.Onces. Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
parent
2ca6dd1f1d
commit
9ad36d17a3
108
version/prop.go
108
version/prop.go
@ -4,34 +4,126 @@
|
|||||||
package version
|
package version
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsMobile reports whether this is a mobile client build.
|
// IsMobile reports whether this is a mobile client build.
|
||||||
func IsMobile() bool { return isMobile }
|
func IsMobile() bool {
|
||||||
|
return runtime.GOOS == "android" || runtime.GOOS == "ios"
|
||||||
|
}
|
||||||
|
|
||||||
// OS returns runtime.GOOS, except instead of returning "darwin" it
|
// OS returns runtime.GOOS, except instead of returning "darwin" it returns
|
||||||
// returns "iOS" or "macOS".
|
// "iOS" or "macOS".
|
||||||
func OS() string { return legacyOS }
|
func OS() string {
|
||||||
|
// If you're wondering why we have this function that just returns
|
||||||
|
// runtime.GOOS written differently: in the old days, Go reported
|
||||||
|
// GOOS=darwin for both iOS and macOS, so we needed this function to
|
||||||
|
// differentiate them. Then a later Go release added GOOS=ios as a separate
|
||||||
|
// platform, but by then the "iOS" and "macOS" values we'd picked, with that
|
||||||
|
// exact capitalization, were already baked into databases.
|
||||||
|
if runtime.GOOS == "ios" {
|
||||||
|
return "iOS"
|
||||||
|
}
|
||||||
|
if runtime.GOOS == "darwin" {
|
||||||
|
return "macOS"
|
||||||
|
}
|
||||||
|
return runtime.GOOS
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
macFlavorOnce sync.Once
|
||||||
|
isMacSysExt bool
|
||||||
|
isMacSandboxed bool
|
||||||
|
)
|
||||||
|
|
||||||
|
func initMacFlavor() {
|
||||||
|
exe, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isMacSysExt = filepath.Base(exe) == "io.tailscale.ipn.macsys.network-extension"
|
||||||
|
isMacSandboxed = isMacSysExt || strings.HasSuffix(exe, "/Contents/MacOS/Tailscale") || strings.HasSuffix(exe, "/Contents/MacOS/IPNExtension")
|
||||||
|
}
|
||||||
|
|
||||||
// IsSandboxedMacOS reports whether this process is a sandboxed macOS
|
// IsSandboxedMacOS reports whether this process is a sandboxed macOS
|
||||||
// process (either the app or the extension). It is true for the Mac App Store
|
// process (either the app or the extension). It is true for the Mac App Store
|
||||||
// and macsys (System Extension) version on macOS, and false for
|
// and macsys (System Extension) version on macOS, and false for
|
||||||
// tailscaled-on-macOS.
|
// tailscaled-on-macOS.
|
||||||
func IsSandboxedMacOS() bool { return isSandboxedMacOS }
|
func IsSandboxedMacOS() bool {
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
macFlavorOnce.Do(initMacFlavor)
|
||||||
|
return isMacSandboxed
|
||||||
|
}
|
||||||
|
|
||||||
// IsMacSysExt whether this binary is from the standalone "System
|
// IsMacSysExt whether this binary is from the standalone "System
|
||||||
// Extension" (a.k.a. "macsys") version of Tailscale for macOS.
|
// Extension" (a.k.a. "macsys") version of Tailscale for macOS.
|
||||||
func IsMacSysExt() bool { return isMacSysExt }
|
func IsMacSysExt() bool {
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
macFlavorOnce.Do(initMacFlavor)
|
||||||
|
return isMacSysExt
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
winFlavorOnce sync.Once
|
||||||
|
isWindowsGUI bool
|
||||||
|
)
|
||||||
|
|
||||||
|
func initWinFlavor() {
|
||||||
|
exe, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isWindowsGUI = strings.EqualFold(exe, "tailscale-ipn.exe") || strings.EqualFold(exe, "tailscale-ipn")
|
||||||
|
}
|
||||||
|
|
||||||
// IsWindowsGUI reports whether the current process is the Windows GUI.
|
// IsWindowsGUI reports whether the current process is the Windows GUI.
|
||||||
func IsWindowsGUI() bool { return isWindowsGUI }
|
func IsWindowsGUI() bool {
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
exe, _ := os.Executable()
|
||||||
|
exe = filepath.Base(exe)
|
||||||
|
return strings.EqualFold(exe, "tailscale-ipn.exe") || strings.EqualFold(exe, "tailscale-ipn")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
isUnstableOnce sync.Once
|
||||||
|
isUnstableBuild bool
|
||||||
|
)
|
||||||
|
|
||||||
// IsUnstableBuild reports whether this is an unstable build.
|
// IsUnstableBuild reports whether this is an unstable build.
|
||||||
// That is, whether its minor version number is odd.
|
// That is, whether its minor version number is odd.
|
||||||
func IsUnstableBuild() bool { return isUnstable }
|
func IsUnstableBuild() bool {
|
||||||
|
isUnstableOnce.Do(initUnstable)
|
||||||
|
return isUnstableBuild
|
||||||
|
}
|
||||||
|
|
||||||
|
func initUnstable() {
|
||||||
|
_, rest, ok := strings.Cut(Short, ".")
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
minorStr, _, ok := strings.Cut(rest, ".")
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
minor, err := strconv.Atoi(minorStr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isUnstableBuild = minor%2 == 1
|
||||||
|
}
|
||||||
|
|
||||||
// Meta is a JSON-serializable type that contains all the version
|
// Meta is a JSON-serializable type that contains all the version
|
||||||
// information.
|
// information.
|
||||||
|
@ -5,93 +5,29 @@
|
|||||||
package version
|
package version
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
tailscaleroot "tailscale.com"
|
tailscaleroot "tailscale.com"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// Long is a full version number for this build, of the form
|
||||||
// Long is a full version number for this build, of the form
|
// "x.y.z-commithash" for builds stamped in the usual way (see
|
||||||
// "x.y.z-commithash" for builds stamped in the usual way (see build_dist.sh
|
// build_dist.sh in the root) or, for binaries built by hand with the
|
||||||
// in the root) or, for binaries built by hand with the go tool, it's of the
|
// go tool, it's of the form "1.23.0-dev20220316-t29837428937{,-dirty}"
|
||||||
// form "1.23.0-dev20220316-t29837428937{,-dirty}" where "1.23.0" comes from
|
// where "1.23.0" comes from ../VERSION.txt and the part after dev
|
||||||
// ../VERSION.txt and the part after dev is YYYYMMDD of the commit time, and
|
// is YYYYMMDD of the commit time, and the part after -t is the commit
|
||||||
// the part after -t is the commit hash. The dirty suffix is whether there
|
// hash. The dirty suffix is whether there are uncommitted changes.
|
||||||
// are uncommitted changes.
|
var Long = ""
|
||||||
Long string
|
|
||||||
|
|
||||||
// Short is a short version number for this build, of the form
|
// Short is a short version number for this build, of the form
|
||||||
// "x.y.z" for builds stamped in the usual way (see
|
// "x.y.z" for builds stamped in the usual way (see
|
||||||
// build_dist.sh in the root) or, for binaries built by hand with the
|
// build_dist.sh in the root) or, for binaries built by hand with the
|
||||||
// go tool, it's like Long's dev form, but ending at the date part,
|
// go tool, it's like Long's dev form, but ending at the date part,
|
||||||
// of the form "1.23.0-dev20220316".
|
// of the form "1.23.0-dev20220316".
|
||||||
Short string
|
var Short = ""
|
||||||
|
|
||||||
// GitCommit, if non-empty, is the git commit of the
|
|
||||||
// github.com/tailscale/tailscale repository at which Tailscale was
|
|
||||||
// built. Its format is the one returned by `git describe --always
|
|
||||||
// --exclude "*" --dirty --abbrev=200`.
|
|
||||||
GitCommit string
|
|
||||||
|
|
||||||
// GitDirty is whether Go stamped the binary as having dirty version
|
|
||||||
// control changes in the working directory (debug.ReadBuildInfo
|
|
||||||
// setting "vcs.modified" was true).
|
|
||||||
GitDirty bool
|
|
||||||
|
|
||||||
// ExtraGitCommit, if non-empty, is the git commit of a "supplemental"
|
|
||||||
// repository at which Tailscale was built. Its format is the same as
|
|
||||||
// gitCommit.
|
|
||||||
//
|
|
||||||
// ExtraGitCommit is used to track the source revision when the main
|
|
||||||
// Tailscale repository is integrated into and built from another
|
|
||||||
// repository (for example, Tailscale's proprietary code, or the
|
|
||||||
// Android OSS repository). Together, GitCommit and ExtraGitCommit
|
|
||||||
// exactly describe what repositories and commits were used in a
|
|
||||||
// build.
|
|
||||||
ExtraGitCommit = ""
|
|
||||||
|
|
||||||
// isUnstable is whether the current build appears to be an unstable, i.e. with
|
|
||||||
// an odd minor version number.
|
|
||||||
isUnstable bool
|
|
||||||
|
|
||||||
// legacyOS is runtime.GOOS, except on apple devices where it's either "iOS" or
|
|
||||||
// "macOS" (with that exact case).
|
|
||||||
//
|
|
||||||
// This used to be a thing because Go reported both macOS and iOS as "darwin"
|
|
||||||
// and we needed to tell them apart. But then Go learned GOOS=ios and
|
|
||||||
// GOOS=darwin as separate things, but we're still stuck with this function
|
|
||||||
// because of the odd casing we picked, which has ossified into databases.
|
|
||||||
legacyOS string
|
|
||||||
|
|
||||||
// isMobile is whether the current build is for a mobile device.
|
|
||||||
isMobile bool
|
|
||||||
|
|
||||||
// isSandboxedMacOS is whether the current binary is any binary in the mac store
|
|
||||||
// or standalone sysext mac apps.
|
|
||||||
isSandboxedMacOS bool
|
|
||||||
|
|
||||||
// isMacSysExt is whether the current binary is the mac system extension binary.
|
|
||||||
isMacSysExt bool
|
|
||||||
|
|
||||||
// isWindowsGUI is whether the current binary is the Windows GUI binary.
|
|
||||||
isWindowsGUI bool
|
|
||||||
|
|
||||||
// majorMinorPatch is the major.minor.patch portion of Short.
|
|
||||||
majorMinorPatch string
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
initVersion()
|
|
||||||
initUnstable()
|
|
||||||
initMiscTraits()
|
|
||||||
}
|
|
||||||
|
|
||||||
func initVersion() {
|
|
||||||
defer func() {
|
defer func() {
|
||||||
// Must be run after Short has been initialized, easiest way to do that
|
// Must be run after Short has been initialized, easiest way to do that
|
||||||
// is a defer.
|
// is a defer.
|
||||||
@ -139,38 +75,28 @@ func initVersion() {
|
|||||||
Long = Short + "-t" + commitHashAbbrev + dirty
|
Long = Short + "-t" + commitHashAbbrev + dirty
|
||||||
}
|
}
|
||||||
|
|
||||||
func initUnstable() {
|
// GitCommit, if non-empty, is the git commit of the
|
||||||
_, rest, ok := strings.Cut(Short, ".")
|
// github.com/tailscale/tailscale repository at which Tailscale was
|
||||||
if !ok {
|
// built. Its format is the one returned by `git describe --always
|
||||||
return
|
// --exclude "*" --dirty --abbrev=200`.
|
||||||
}
|
var GitCommit = ""
|
||||||
minorStr, _, ok := strings.Cut(rest, ".")
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
minor, err := strconv.Atoi(minorStr)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
isUnstable = minor%2 == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func initMiscTraits() {
|
// GitDirty is whether Go stamped the binary as having dirty version
|
||||||
exe, _ := os.Executable()
|
// control changes in the working directory (debug.ReadBuildInfo
|
||||||
base := filepath.Base(exe)
|
// setting "vcs.modified" was true).
|
||||||
|
var GitDirty bool
|
||||||
|
|
||||||
legacyOS = runtime.GOOS
|
// ExtraGitCommit, if non-empty, is the git commit of a "supplemental"
|
||||||
switch runtime.GOOS {
|
// repository at which Tailscale was built. Its format is the same as
|
||||||
case "darwin":
|
// gitCommit.
|
||||||
legacyOS = "macOS"
|
//
|
||||||
isMacSysExt = strings.HasPrefix(base, "io.tailscale.ipn.macsys.network-extension")
|
// ExtraGitCommit is used to track the source revision when the main
|
||||||
isSandboxedMacOS = isMacSysExt || strings.HasSuffix(exe, "/Contents/MacOS/Tailscale") || strings.HasSuffix(exe, "/Contents/MacOS/IPNExtension")
|
// Tailscale repository is integrated into and built from another
|
||||||
case "ios":
|
// repository (for example, Tailscale's proprietary code, or the
|
||||||
legacyOS = "iOS"
|
// Android OSS repository). Together, GitCommit and ExtraGitCommit
|
||||||
isMobile = true
|
// exactly describe what repositories and commits were used in a
|
||||||
case "android":
|
// build.
|
||||||
isMobile = true
|
var ExtraGitCommit = ""
|
||||||
case "windows":
|
|
||||||
isWindowsGUI = strings.EqualFold(base, "tailscale-ipn.exe") || strings.EqualFold(base, "tailscale-ipn")
|
// majorMinorPatch is the major.minor.patch portion of Short.
|
||||||
}
|
var majorMinorPatch string
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user