mirror of
https://github.com/netbirdio/netbird.git
synced 2026-03-31 06:34:19 -04:00
This PR refactors the system information collection code by moving static system information gathering to a dedicated location and separating platform-specific implementations. The primary goal is to improve code organization and maintainability by centralizing static info collection logic. Key changes: - Centralized static info collection into dedicated files with platform-specific implementations - Moved `StaticInfo` struct definition to the main static_info.go file - Added async initialization function `UpdateStaticInfoAsync()` across all platforms
185 lines
3.7 KiB
Go
185 lines
3.7 KiB
Go
package system
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
"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"
|
|
)
|
|
|
|
type Win32_OperatingSystem struct {
|
|
Caption string
|
|
}
|
|
|
|
type Win32_ComputerSystem struct {
|
|
Manufacturer string
|
|
}
|
|
|
|
type Win32_ComputerSystemProduct struct {
|
|
Name string
|
|
}
|
|
|
|
type Win32_BIOS struct {
|
|
SerialNumber string
|
|
}
|
|
|
|
func newStaticInfo() StaticInfo {
|
|
si := StaticInfo{}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
wg := sync.WaitGroup{}
|
|
wg.Add(1)
|
|
go func() {
|
|
si.SystemSerialNumber, si.SystemProductName, si.SystemManufacturer = sysInfo()
|
|
wg.Done()
|
|
}()
|
|
wg.Add(1)
|
|
go func() {
|
|
si.Environment.Cloud = detect_cloud.Detect(ctx)
|
|
wg.Done()
|
|
}()
|
|
wg.Add(1)
|
|
go func() {
|
|
si.Environment.Platform = detect_platform.Detect(ctx)
|
|
wg.Done()
|
|
}()
|
|
wg.Add(1)
|
|
go func() {
|
|
si.OSName, si.OSVersion = getOSNameAndVersion()
|
|
wg.Done()
|
|
}()
|
|
wg.Add(1)
|
|
go func() {
|
|
si.BuildVersion = getBuildVersion()
|
|
wg.Done()
|
|
}()
|
|
wg.Wait()
|
|
return si
|
|
}
|
|
|
|
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 sysNumber() (string, error) {
|
|
var dst []Win32_BIOS
|
|
query := wmi.CreateQuery(&dst, "")
|
|
err := wmi.Query(query, &dst)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return dst[0].SerialNumber, nil
|
|
}
|
|
|
|
func sysProductName() (string, error) {
|
|
var dst []Win32_ComputerSystemProduct
|
|
query := wmi.CreateQuery(&dst, "")
|
|
err := wmi.Query(query, &dst)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
// `ComputerSystemProduct` could be empty on some virtualized systems
|
|
if len(dst) < 1 {
|
|
return "unknown", nil
|
|
}
|
|
return dst[0].Name, nil
|
|
}
|
|
|
|
func sysManufacturer() (string, error) {
|
|
var dst []Win32_ComputerSystem
|
|
query := wmi.CreateQuery(&dst, "")
|
|
err := wmi.Query(query, &dst)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return dst[0].Manufacturer, nil
|
|
}
|
|
|
|
func getOSNameAndVersion() (string, string) {
|
|
var dst []Win32_OperatingSystem
|
|
query := wmi.CreateQuery(&dst, "")
|
|
err := wmi.Query(query, &dst)
|
|
if err != nil {
|
|
log.Error(err)
|
|
return "Windows", getBuildVersion()
|
|
}
|
|
|
|
if len(dst) == 0 {
|
|
return "Windows", getBuildVersion()
|
|
}
|
|
|
|
split := strings.Split(dst[0].Caption, " ")
|
|
|
|
if len(split) <= 3 {
|
|
return "Windows", getBuildVersion()
|
|
}
|
|
|
|
name := split[1]
|
|
version := split[2]
|
|
if split[2] == "Server" {
|
|
name = fmt.Sprintf("%s %s", split[1], split[2])
|
|
version = split[3]
|
|
}
|
|
|
|
return name, version
|
|
}
|
|
|
|
func getBuildVersion() string {
|
|
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
|
if err != nil {
|
|
log.Error(err)
|
|
return "0.0.0.0"
|
|
}
|
|
defer func() {
|
|
deferErr := k.Close()
|
|
if deferErr != nil {
|
|
log.Error(deferErr)
|
|
}
|
|
}()
|
|
|
|
major, _, err := k.GetIntegerValue("CurrentMajorVersionNumber")
|
|
if err != nil {
|
|
log.Error(err)
|
|
}
|
|
minor, _, err := k.GetIntegerValue("CurrentMinorVersionNumber")
|
|
if err != nil {
|
|
log.Error(err)
|
|
}
|
|
build, _, err := k.GetStringValue("CurrentBuildNumber")
|
|
if err != nil {
|
|
log.Error(err)
|
|
}
|
|
// Update Build Revision
|
|
ubr, _, err := k.GetIntegerValue("UBR")
|
|
if err != nil {
|
|
log.Error(err)
|
|
}
|
|
ver := fmt.Sprintf("%d.%d.%s.%d", major, minor, build, ubr)
|
|
return ver
|
|
}
|