Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[client] Get static system info once #2965

Merged
merged 11 commits into from
Dec 3, 2024
8 changes: 8 additions & 0 deletions client/system/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ type Info struct {
Files []File // for posture checks
}

// StaticInfo is an object that contains machine information that does not change
type StaticInfo struct {
SystemSerialNumber string
SystemProductName string
SystemManufacturer string
Environment Environment
}

// extractUserAgent extracts Netbird's agent (client) name and version from the outgoing context
func extractUserAgent(ctx context.Context) string {
md, hasMeta := metadata.FromOutgoingContext(ctx)
Expand Down
20 changes: 9 additions & 11 deletions client/system/info_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ import (
"os/exec"
"runtime"
"strings"
"time"

"golang.org/x/sys/unix"

log "github.com/sirupsen/logrus"

"github.com/netbirdio/netbird/client/system/detect_cloud"
"github.com/netbirdio/netbird/client/system/detect_platform"
"github.com/netbirdio/netbird/version"
)

Expand All @@ -41,11 +40,10 @@ func GetInfo(ctx context.Context) *Info {
log.Warnf("failed to discover network addresses: %s", err)
}

serialNum, prodName, manufacturer := sysInfo()

env := Environment{
Cloud: detect_cloud.Detect(ctx),
Platform: detect_platform.Detect(ctx),
start := time.Now()
si := updateStaticInfo()
if time.Since(start) > 1*time.Second {
log.Warnf("updateStaticInfo took %s", time.Since(start))
}

gio := &Info{
Expand All @@ -57,10 +55,10 @@ func GetInfo(ctx context.Context) *Info {
CPUs: runtime.NumCPU(),
KernelVersion: release,
NetworkAddresses: addrs,
SystemSerialNumber: serialNum,
SystemProductName: prodName,
SystemManufacturer: manufacturer,
Environment: env,
SystemSerialNumber: si.SystemSerialNumber,
SystemProductName: si.SystemProductName,
SystemManufacturer: si.SystemManufacturer,
Environment: si.Environment,
}

systemHostname, _ := os.Hostname()
Expand Down
61 changes: 27 additions & 34 deletions client/system/info_linux.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//go:build !android
// +build !android

package system

Expand All @@ -16,30 +15,13 @@ import (
log "github.com/sirupsen/logrus"
"github.com/zcalusic/sysinfo"

"github.com/netbirdio/netbird/client/system/detect_cloud"
"github.com/netbirdio/netbird/client/system/detect_platform"
"github.com/netbirdio/netbird/version"
)

type SysInfoGetter interface {
GetSysInfo() SysInfo
}

type SysInfoWrapper struct {
si sysinfo.SysInfo
}

func (s SysInfoWrapper) GetSysInfo() SysInfo {
s.si.GetSysInfo()
return SysInfo{
ChassisSerial: s.si.Chassis.Serial,
ProductSerial: s.si.Product.Serial,
BoardSerial: s.si.Board.Serial,
ProductName: s.si.Product.Name,
BoardName: s.si.Board.Name,
ProductVendor: s.si.Product.Vendor,
}
}
var (
// it is override in tests
getSystemInfo = defaultSysInfoImplementation
)

// GetInfo retrieves and parses the system information
func GetInfo(ctx context.Context) *Info {
Expand All @@ -65,12 +47,10 @@ func GetInfo(ctx context.Context) *Info {
log.Warnf("failed to discover network addresses: %s", err)
}

si := SysInfoWrapper{}
serialNum, prodName, manufacturer := sysInfo(si.GetSysInfo())

env := Environment{
Cloud: detect_cloud.Detect(ctx),
Platform: detect_platform.Detect(ctx),
start := time.Now()
si := updateStaticInfo()
if time.Since(start) > 1*time.Second {
log.Warnf("updateStaticInfo took %s", time.Since(start))
}

gio := &Info{
Expand All @@ -85,10 +65,10 @@ func GetInfo(ctx context.Context) *Info {
UIVersion: extractUserAgent(ctx),
KernelVersion: osInfo[1],
NetworkAddresses: addrs,
SystemSerialNumber: serialNum,
SystemProductName: prodName,
SystemManufacturer: manufacturer,
Environment: env,
SystemSerialNumber: si.SystemSerialNumber,
SystemProductName: si.SystemProductName,
SystemManufacturer: si.SystemManufacturer,
Environment: si.Environment,
}

return gio
Expand All @@ -108,9 +88,9 @@ func _getInfo() string {
return out.String()
}

func sysInfo(si SysInfo) (string, string, string) {
func sysInfo() (string, string, string) {
isascii := regexp.MustCompile("^[[:ascii:]]+$")

si := getSystemInfo()
serials := []string{si.ChassisSerial, si.ProductSerial}
serial := ""

Expand Down Expand Up @@ -141,3 +121,16 @@ func sysInfo(si SysInfo) (string, string, string) {
}
return serial, name, manufacturer
}

func defaultSysInfoImplementation() SysInfo {
si := sysinfo.SysInfo{}
si.GetSysInfo()
return SysInfo{
ChassisSerial: si.Chassis.Serial,
ProductSerial: si.Product.Serial,
BoardSerial: si.Board.Serial,
ProductName: si.Product.Name,
BoardName: si.Board.Name,
ProductVendor: si.Product.Vendor,
}
}
53 changes: 29 additions & 24 deletions client/system/info_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import (
"os"
"runtime"
"strings"
"time"

log "github.com/sirupsen/logrus"
"github.com/yusufpapurcu/wmi"
"golang.org/x/sys/windows/registry"

"github.com/netbirdio/netbird/client/system/detect_cloud"
"github.com/netbirdio/netbird/client/system/detect_platform"
"github.com/netbirdio/netbird/version"
)

Expand Down Expand Up @@ -42,24 +41,10 @@ func GetInfo(ctx context.Context) *Info {
log.Warnf("failed to discover network addresses: %s", err)
}

serialNum, err := sysNumber()
if err != nil {
log.Warnf("failed to get system serial number: %s", err)
}

prodName, err := sysProductName()
if err != nil {
log.Warnf("failed to get system product name: %s", err)
}

manufacturer, err := sysManufacturer()
if err != nil {
log.Warnf("failed to get system manufacturer: %s", err)
}

env := Environment{
Cloud: detect_cloud.Detect(ctx),
Platform: detect_platform.Detect(ctx),
start := time.Now()
si := updateStaticInfo()
if time.Since(start) > 1*time.Second {
log.Warnf("updateStaticInfo took %s", time.Since(start))
}

gio := &Info{
Expand All @@ -71,10 +56,10 @@ func GetInfo(ctx context.Context) *Info {
CPUs: runtime.NumCPU(),
KernelVersion: buildVersion,
NetworkAddresses: addrs,
SystemSerialNumber: serialNum,
SystemProductName: prodName,
SystemManufacturer: manufacturer,
Environment: env,
SystemSerialNumber: si.SystemSerialNumber,
SystemProductName: si.SystemProductName,
SystemManufacturer: si.SystemManufacturer,
Environment: si.Environment,
}

systemHostname, _ := os.Hostname()
Expand All @@ -85,6 +70,26 @@ func GetInfo(ctx context.Context) *Info {
return gio
}

func sysInfo() (serialNumber string, productName string, manufacturer string) {
var err error
serialNumber, err = sysNumber()
if err != nil {
log.Warnf("failed to get system serial number: %s", err)
}

productName, err = sysProductName()
if err != nil {
log.Warnf("failed to get system product name: %s", err)
}

manufacturer, err = sysManufacturer()
if err != nil {
log.Warnf("failed to get system manufacturer: %s", err)
}

return serialNumber, productName, manufacturer
}

func getOSNameAndVersion() (string, string) {
var dst []Win32_OperatingSystem
query := wmi.CreateQuery(&dst, "")
Expand Down
46 changes: 46 additions & 0 deletions client/system/static_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//go:build (linux && !android) || windows || (darwin && !ios)

package system

import (
"context"
"sync"
"time"

"github.com/netbirdio/netbird/client/system/detect_cloud"
"github.com/netbirdio/netbird/client/system/detect_platform"
)

var (
staticInfo StaticInfo
once sync.Once
)

func init() {
go func() {
_ = updateStaticInfo()
}()
}

func updateStaticInfo() StaticInfo {
once.Do(func() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
wg := sync.WaitGroup{}
wg.Add(3)
go func() {
staticInfo.SystemSerialNumber, staticInfo.SystemProductName, staticInfo.SystemManufacturer = sysInfo()
wg.Done()
}()
go func() {
staticInfo.Environment.Cloud = detect_cloud.Detect(ctx)
wg.Done()
}()
go func() {
staticInfo.Environment.Platform = detect_platform.Detect(ctx)
wg.Done()
}()
wg.Wait()
})
return staticInfo
}
5 changes: 4 additions & 1 deletion client/system/sysinfo_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ func Test_sysInfo(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotSerialNum, gotProdName, gotManufacturer := sysInfo(tt.sysInfo)
getSystemInfo = func() SysInfo {
return tt.sysInfo
}
gotSerialNum, gotProdName, gotManufacturer := sysInfo()
if gotSerialNum != tt.wantSerialNum {
t.Errorf("sysInfo() gotSerialNum = %v, want %v", gotSerialNum, tt.wantSerialNum)
}
Expand Down
Loading