2020-09-11 02:55:09 +00:00
|
|
|
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
// Package distro reports which distro we're running on.
|
|
|
|
package distro
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"runtime"
|
2022-07-18 15:47:37 +00:00
|
|
|
"strconv"
|
2022-08-04 17:43:49 +00:00
|
|
|
|
|
|
|
"tailscale.com/syncs"
|
2020-09-11 02:55:09 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Distro string
|
|
|
|
|
|
|
|
const (
|
2022-06-05 04:34:06 +00:00
|
|
|
Debian = Distro("debian")
|
|
|
|
Arch = Distro("arch")
|
|
|
|
Synology = Distro("synology")
|
|
|
|
OpenWrt = Distro("openwrt")
|
|
|
|
NixOS = Distro("nixos")
|
|
|
|
QNAP = Distro("qnap")
|
|
|
|
Pfsense = Distro("pfsense")
|
|
|
|
OPNsense = Distro("opnsense")
|
|
|
|
TrueNAS = Distro("truenas")
|
|
|
|
Gokrazy = Distro("gokrazy")
|
|
|
|
WDMyCloud = Distro("wdmycloud")
|
2020-09-11 02:55:09 +00:00
|
|
|
)
|
|
|
|
|
2022-08-04 17:43:49 +00:00
|
|
|
var distroAtomic syncs.AtomicValue[Distro]
|
2022-03-02 03:26:57 +00:00
|
|
|
|
2020-09-11 02:55:09 +00:00
|
|
|
// Get returns the current distro, or the empty string if unknown.
|
|
|
|
func Get() Distro {
|
2022-08-04 17:43:49 +00:00
|
|
|
if d, ok := distroAtomic.LoadOk(); ok {
|
2022-03-02 03:26:57 +00:00
|
|
|
return d
|
2020-09-11 02:55:09 +00:00
|
|
|
}
|
2022-08-04 17:43:49 +00:00
|
|
|
var d Distro
|
2022-03-02 03:26:57 +00:00
|
|
|
switch runtime.GOOS {
|
|
|
|
case "linux":
|
|
|
|
d = linuxDistro()
|
|
|
|
case "freebsd":
|
|
|
|
d = freebsdDistro()
|
2021-09-06 20:17:45 +00:00
|
|
|
}
|
2022-03-02 03:26:57 +00:00
|
|
|
distroAtomic.Store(d) // even if empty
|
|
|
|
return d
|
2020-09-11 02:55:09 +00:00
|
|
|
}
|
|
|
|
|
2020-12-22 04:57:35 +00:00
|
|
|
func have(file string) bool {
|
|
|
|
_, err := os.Stat(file)
|
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func haveDir(file string) bool {
|
|
|
|
fi, err := os.Stat(file)
|
|
|
|
return err == nil && fi.IsDir()
|
|
|
|
}
|
|
|
|
|
2020-09-11 02:55:09 +00:00
|
|
|
func linuxDistro() Distro {
|
2020-12-22 04:57:35 +00:00
|
|
|
switch {
|
2021-04-01 23:24:53 +00:00
|
|
|
case haveDir("/usr/syno"):
|
2020-09-11 02:55:09 +00:00
|
|
|
return Synology
|
2021-12-08 02:37:15 +00:00
|
|
|
case have("/usr/local/bin/freenas-debug"):
|
|
|
|
// TrueNAS Scale runs on debian
|
|
|
|
return TrueNAS
|
2020-12-22 04:57:35 +00:00
|
|
|
case have("/etc/debian_version"):
|
2020-09-11 02:55:09 +00:00
|
|
|
return Debian
|
2020-12-22 04:57:35 +00:00
|
|
|
case have("/etc/arch-release"):
|
2020-09-11 02:55:09 +00:00
|
|
|
return Arch
|
2020-12-22 04:57:35 +00:00
|
|
|
case have("/etc/openwrt_version"):
|
2020-09-22 17:28:40 +00:00
|
|
|
return OpenWrt
|
2020-12-22 04:57:35 +00:00
|
|
|
case have("/run/current-system/sw/bin/nixos-version"):
|
|
|
|
return NixOS
|
2021-06-10 08:08:02 +00:00
|
|
|
case have("/etc/config/uLinux.conf"):
|
|
|
|
return QNAP
|
2022-03-02 03:26:57 +00:00
|
|
|
case haveDir("/gokrazy"):
|
|
|
|
return Gokrazy
|
2022-06-05 04:34:06 +00:00
|
|
|
case have("/usr/local/wdmcserver/bin/wdmc.xml"): // Western Digital MyCloud OS3
|
|
|
|
return WDMyCloud
|
|
|
|
case have("/usr/sbin/wd_crontab.sh"): // Western Digital MyCloud OS5
|
|
|
|
return WDMyCloud
|
2020-09-22 17:28:40 +00:00
|
|
|
}
|
2020-09-11 02:55:09 +00:00
|
|
|
return ""
|
|
|
|
}
|
2021-09-06 20:17:45 +00:00
|
|
|
|
|
|
|
func freebsdDistro() Distro {
|
|
|
|
switch {
|
|
|
|
case have("/etc/pfSense-rc"):
|
|
|
|
return Pfsense
|
|
|
|
case have("/usr/local/sbin/opnsense-shell"):
|
|
|
|
return OPNsense
|
|
|
|
case have("/usr/local/bin/freenas-debug"):
|
2021-12-08 02:37:15 +00:00
|
|
|
// TrueNAS Core runs on FreeBSD
|
2021-09-06 20:17:45 +00:00
|
|
|
return TrueNAS
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|
2022-07-18 15:47:37 +00:00
|
|
|
|
|
|
|
// DSMVersion reports the Synology DSM major version.
|
|
|
|
//
|
|
|
|
// If not Synology, it reports 0.
|
|
|
|
func DSMVersion() int {
|
|
|
|
if runtime.GOOS != "linux" {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
if Get() != Synology {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
v, _ := strconv.Atoi(os.Getenv("SYNOPKG_DSM_VERSION_MAJOR"))
|
|
|
|
return v
|
|
|
|
}
|