From b9dd3fa534055f303eb09576d33ee3ba6fd739bc Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 2 Dec 2022 09:35:49 -0800 Subject: [PATCH] paths, version/distro: detect Synology DSM version better, use for socket path Resolves a TODO in the code noted while discussing QNAP defaults. Tested on DSM6 and DSM7. Change-Id: Icce03ff41fafd7b3a358cfee16f2ed13d5cc3c5d Signed-off-by: Brad Fitzpatrick --- paths/paths.go | 12 ++++-------- version/distro/distro.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/paths/paths.go b/paths/paths.go index e6b461856..7fb9b0c03 100644 --- a/paths/paths.go +++ b/paths/paths.go @@ -30,15 +30,11 @@ func DefaultTailscaledSocket() string { } switch distro.Get() { case distro.Synology: - // TODO(maisem): be smarter about this. We can parse /etc/VERSION. - const dsm6Sock = "/var/packages/Tailscale/etc/tailscaled.sock" - const dsm7Sock = "/var/packages/Tailscale/var/tailscaled.sock" - if fi, err := os.Stat(dsm6Sock); err == nil && !fi.IsDir() { - return dsm6Sock - } - if fi, err := os.Stat(dsm7Sock); err == nil && !fi.IsDir() { - return dsm7Sock + if distro.DSMVersion() == 6 { + return "/var/packages/Tailscale/etc/tailscaled.sock" } + // DSM 7 (and higher? or failure to detect.) + return "/var/packages/Tailscale/var/tailscaled.sock" case distro.Gokrazy: return "/perm/tailscaled/tailscaled.sock" } diff --git a/version/distro/distro.go b/version/distro/distro.go index 3b1d36378..64f49f2ef 100644 --- a/version/distro/distro.go +++ b/version/distro/distro.go @@ -6,11 +6,14 @@ package distro import ( + "bytes" + "io" "os" "runtime" "strconv" "tailscale.com/syncs" + "tailscale.com/util/lineread" ) type Distro string @@ -97,6 +100,8 @@ func freebsdDistro() Distro { return "" } +var dsmVersion syncs.AtomicValue[int] + // DSMVersion reports the Synology DSM major version. // // If not Synology, it reports 0. @@ -107,6 +112,30 @@ func DSMVersion() int { if Get() != Synology { return 0 } + if v, ok := dsmVersion.LoadOk(); ok && v != 0 { + return v + } + // This is set when running as a package: v, _ := strconv.Atoi(os.Getenv("SYNOPKG_DSM_VERSION_MAJOR")) + if v != 0 { + dsmVersion.Store(v) + return v + } + // But when run from the command line, we have to read it from the file: + lineread.File("/etc/VERSION", func(line []byte) error { + line = bytes.TrimSpace(line) + if string(line) == `majorversion="7"` { + v = 7 + return io.EOF + } + if string(line) == `majorversion="6"` { + v = 6 + return io.EOF + } + return nil + }) + if v != 0 { + dsmVersion.Store(v) + } return v }