This was meant to be part of 47045265b9
which instead deleted them :(
Updates tailscale/corp#1959
main
parent
71b375c502
commit
3ac731dda1
@ -0,0 +1,93 @@ |
||||
// 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.
|
||||
|
||||
//go:build linux && !android
|
||||
// +build linux,!android
|
||||
|
||||
package hostinfo |
||||
|
||||
import ( |
||||
"bytes" |
||||
"fmt" |
||||
"io/ioutil" |
||||
"strings" |
||||
"syscall" |
||||
|
||||
"tailscale.com/util/lineread" |
||||
"tailscale.com/version/distro" |
||||
) |
||||
|
||||
func init() { |
||||
osVersion = osVersionLinux |
||||
} |
||||
|
||||
func osVersionLinux() string { |
||||
dist := distro.Get() |
||||
propFile := "/etc/os-release" |
||||
switch dist { |
||||
case distro.Synology: |
||||
propFile = "/etc.defaults/VERSION" |
||||
case distro.OpenWrt: |
||||
propFile = "/etc/openwrt_release" |
||||
} |
||||
|
||||
m := map[string]string{} |
||||
lineread.File(propFile, func(line []byte) error { |
||||
eq := bytes.IndexByte(line, '=') |
||||
if eq == -1 { |
||||
return nil |
||||
} |
||||
k, v := string(line[:eq]), strings.Trim(string(line[eq+1:]), `"'`) |
||||
m[k] = v |
||||
return nil |
||||
}) |
||||
|
||||
var un syscall.Utsname |
||||
syscall.Uname(&un) |
||||
|
||||
var attrBuf strings.Builder |
||||
attrBuf.WriteString("; kernel=") |
||||
for _, b := range un.Release { |
||||
if b == 0 { |
||||
break |
||||
} |
||||
attrBuf.WriteByte(byte(b)) |
||||
} |
||||
if inContainer() { |
||||
attrBuf.WriteString("; container") |
||||
} |
||||
if env := GetEnvType(); env != "" { |
||||
fmt.Fprintf(&attrBuf, "; env=%s", env) |
||||
} |
||||
attr := attrBuf.String() |
||||
|
||||
id := m["ID"] |
||||
|
||||
switch id { |
||||
case "debian": |
||||
slurp, _ := ioutil.ReadFile("/etc/debian_version") |
||||
return fmt.Sprintf("Debian %s (%s)%s", bytes.TrimSpace(slurp), m["VERSION_CODENAME"], attr) |
||||
case "ubuntu": |
||||
return fmt.Sprintf("Ubuntu %s%s", m["VERSION"], attr) |
||||
case "", "centos": // CentOS 6 has no /etc/os-release, so its id is ""
|
||||
if cr, _ := ioutil.ReadFile("/etc/centos-release"); len(cr) > 0 { // "CentOS release 6.10 (Final)
|
||||
return fmt.Sprintf("%s%s", bytes.TrimSpace(cr), attr) |
||||
} |
||||
fallthrough |
||||
case "fedora", "rhel", "alpine", "nixos": |
||||
// Their PRETTY_NAME is fine as-is for all versions I tested.
|
||||
fallthrough |
||||
default: |
||||
if v := m["PRETTY_NAME"]; v != "" { |
||||
return fmt.Sprintf("%s%s", v, attr) |
||||
} |
||||
} |
||||
switch dist { |
||||
case distro.Synology: |
||||
return fmt.Sprintf("Synology %s%s", m["productversion"], attr) |
||||
case distro.OpenWrt: |
||||
return fmt.Sprintf("OpenWrt %s%s", m["DISTRIB_RELEASE"], attr) |
||||
} |
||||
return fmt.Sprintf("Other%s", attr) |
||||
} |
||||
@ -0,0 +1,29 @@ |
||||
// 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 hostinfo |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"testing" |
||||
) |
||||
|
||||
func TestNew(t *testing.T) { |
||||
hi := New() |
||||
if hi == nil { |
||||
t.Fatal("no Hostinfo") |
||||
} |
||||
j, err := json.MarshalIndent(hi, " ", "") |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
t.Logf("Got: %s", j) |
||||
} |
||||
|
||||
func TestOSVersion(t *testing.T) { |
||||
if osVersion == nil { |
||||
t.Skip("not available for OS") |
||||
} |
||||
t.Logf("Got: %#q", osVersion()) |
||||
} |
||||
@ -0,0 +1,39 @@ |
||||
// 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 hostinfo |
||||
|
||||
import ( |
||||
"os/exec" |
||||
"strings" |
||||
"sync/atomic" |
||||
"syscall" |
||||
) |
||||
|
||||
func init() { |
||||
osVersion = osVersionWindows |
||||
} |
||||
|
||||
var winVerCache atomic.Value // of string
|
||||
|
||||
func osVersionWindows() string { |
||||
if s, ok := winVerCache.Load().(string); ok { |
||||
return s |
||||
} |
||||
cmd := exec.Command("cmd", "/c", "ver") |
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} |
||||
out, _ := cmd.Output() // "\nMicrosoft Windows [Version 10.0.19041.388]\n\n"
|
||||
s := strings.TrimSpace(string(out)) |
||||
s = strings.TrimPrefix(s, "Microsoft Windows [") |
||||
s = strings.TrimSuffix(s, "]") |
||||
|
||||
// "Version 10.x.y.z", with "Version" localized. Keep only stuff after the space.
|
||||
if sp := strings.Index(s, " "); sp != -1 { |
||||
s = s[sp+1:] |
||||
} |
||||
if s != "" { |
||||
winVerCache.Store(s) |
||||
} |
||||
return s // "10.0.19041.388", ideally
|
||||
} |
||||
Loading…
Reference in new issue