mirror of
https://github.com/fankes/komari-agent.git
synced 2025-10-18 18:49:23 +08:00
feat: 增加对 Android 系统的识别支持
This commit is contained in:
@@ -11,14 +11,21 @@ import (
|
||||
)
|
||||
|
||||
func OSName() string {
|
||||
// Check if it's an Android system
|
||||
if androidVersion := detectAndroid(); androidVersion != "" {
|
||||
return androidVersion
|
||||
}
|
||||
|
||||
// Check if it's a Proxmox VE
|
||||
if pveVersion := detectProxmoxVE(); pveVersion != "" {
|
||||
return pveVersion
|
||||
}
|
||||
|
||||
|
||||
// Check if it's a Synology
|
||||
if synologyName := detectSynology(); synologyName != "" {
|
||||
return synologyName
|
||||
}
|
||||
|
||||
|
||||
file, err := os.Open("/etc/os-release")
|
||||
if err != nil {
|
||||
return "Linux"
|
||||
@@ -45,7 +52,7 @@ func detectSynology() string {
|
||||
"/etc/synoinfo.conf",
|
||||
"/etc.defaults/synoinfo.conf",
|
||||
}
|
||||
|
||||
|
||||
for _, file := range synologyFiles {
|
||||
if info, err := os.Stat(file); err == nil && !info.IsDir() {
|
||||
if synologyInfo := readSynologyInfo(file); synologyInfo != "" {
|
||||
@@ -53,11 +60,11 @@ func detectSynology() string {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if info, err := os.Stat("/usr/syno"); err == nil && info.IsDir() {
|
||||
return "Synology DSM"
|
||||
}
|
||||
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -67,37 +74,37 @@ func readSynologyInfo(filename string) string {
|
||||
return ""
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
|
||||
var unique, udcCheckState string
|
||||
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
|
||||
if strings.HasPrefix(line, "unique=") {
|
||||
unique = strings.Trim(strings.TrimPrefix(line, "unique="), `"`)
|
||||
} else if strings.HasPrefix(line, "udc_check_state=") {
|
||||
udcCheckState = strings.Trim(strings.TrimPrefix(line, "udc_check_state="), `"`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if unique != "" && strings.Contains(unique, "synology_") {
|
||||
parts := strings.Split(unique, "_")
|
||||
if len(parts) >= 3 {
|
||||
model := strings.ToUpper(parts[len(parts)-1])
|
||||
|
||||
|
||||
result := "Synology " + model
|
||||
|
||||
|
||||
if udcCheckState != "" {
|
||||
result += " DSM " + udcCheckState
|
||||
} else {
|
||||
result += " DSM"
|
||||
}
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -105,21 +112,21 @@ func detectProxmoxVE() string {
|
||||
if _, err := exec.LookPath("pveversion"); err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
out, err := exec.Command("pveversion").Output()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
output := strings.TrimSpace(string(out))
|
||||
lines := strings.Split(output, "\n")
|
||||
|
||||
|
||||
var version string
|
||||
var codename string
|
||||
|
||||
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
|
||||
if strings.HasPrefix(line, "pve-manager/") {
|
||||
parts := strings.Split(line, "/")
|
||||
if len(parts) >= 2 {
|
||||
@@ -130,9 +137,9 @@ func detectProxmoxVE() string {
|
||||
version = versionPart
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if version != "" {
|
||||
if file, err := os.Open("/etc/os-release"); err == nil {
|
||||
defer file.Close()
|
||||
@@ -146,23 +153,133 @@ func detectProxmoxVE() string {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if version != "" {
|
||||
if codename != "" {
|
||||
return "Proxmox VE " + version + " (" + codename + ")"
|
||||
}
|
||||
return "Proxmox VE " + version
|
||||
}
|
||||
|
||||
|
||||
return "Proxmox VE"
|
||||
}
|
||||
|
||||
// detectAndroid detects if the system is Android and returns detailed information
|
||||
func detectAndroid() string {
|
||||
// 1. Try to get Android version info using the getprop command
|
||||
cmdGetprop := exec.Command("getprop", "ro.build.version.release")
|
||||
version, err := cmdGetprop.Output()
|
||||
if err == nil && len(version) > 0 {
|
||||
versionStr := strings.TrimSpace(string(version))
|
||||
|
||||
// Get device model
|
||||
cmdGetModel := exec.Command("getprop", "ro.product.model")
|
||||
model, err2 := cmdGetModel.Output()
|
||||
modelStr := strings.TrimSpace(string(model))
|
||||
|
||||
// Get manufacturer information
|
||||
cmdGetBrand := exec.Command("getprop", "ro.product.brand")
|
||||
brand, err3 := cmdGetBrand.Output()
|
||||
brandStr := strings.TrimSpace(string(brand))
|
||||
|
||||
result := "Android " + versionStr
|
||||
|
||||
// Add brand and model information (if available)
|
||||
if err2 == nil && modelStr != "" {
|
||||
if err3 == nil && brandStr != "" && brandStr != modelStr {
|
||||
result += " (" + brandStr + " " + modelStr + ")"
|
||||
} else {
|
||||
result += " (" + modelStr + ")"
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// 2. Try to check Android system build.prop file
|
||||
if _, err := os.Stat("/system/build.prop"); err == nil {
|
||||
return readAndroidBuildProp()
|
||||
}
|
||||
|
||||
// 3. Check for typical Android directory structure
|
||||
if isAndroidSystem() {
|
||||
return "Android"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// readAndroidBuildProp reads Android version information from build.prop file
|
||||
func readAndroidBuildProp() string {
|
||||
file, err := os.Open("/system/build.prop")
|
||||
if err != nil {
|
||||
return "Android"
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var version, model, brand string
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
if strings.HasPrefix(line, "ro.build.version.release=") {
|
||||
version = strings.TrimPrefix(line, "ro.build.version.release=")
|
||||
} else if strings.HasPrefix(line, "ro.product.model=") {
|
||||
model = strings.TrimPrefix(line, "ro.product.model=")
|
||||
} else if strings.HasPrefix(line, "ro.product.brand=") {
|
||||
brand = strings.TrimPrefix(line, "ro.product.brand=")
|
||||
}
|
||||
|
||||
// If all information has been collected, we can exit early
|
||||
if version != "" && model != "" && brand != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if version != "" {
|
||||
result := "Android " + version
|
||||
|
||||
if model != "" {
|
||||
if brand != "" && brand != model {
|
||||
result += " (" + brand + " " + model + ")"
|
||||
} else {
|
||||
result += " (" + model + ")"
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
return "Android"
|
||||
}
|
||||
|
||||
// isAndroidSystem determines if the system is Android by checking typical directory structure
|
||||
func isAndroidSystem() bool {
|
||||
androidDirs := []string{
|
||||
"/system/app",
|
||||
"/system/priv-app",
|
||||
"/data/app",
|
||||
"/sdcard",
|
||||
}
|
||||
|
||||
dirCount := 0
|
||||
for _, dir := range androidDirs {
|
||||
if info, err := os.Stat(dir); err == nil && info.IsDir() {
|
||||
dirCount++
|
||||
}
|
||||
}
|
||||
|
||||
// Consider it an Android system only if at least 2 directories exist
|
||||
return dirCount >= 2
|
||||
}
|
||||
|
||||
// KernelVersion returns the kernel version on Linux systems
|
||||
func KernelVersion() string {
|
||||
out, err := exec.Command("uname", "-r").Output()
|
||||
if err != nil {
|
||||
return "Unknown"
|
||||
}
|
||||
|
||||
|
||||
return strings.TrimSpace(string(out))
|
||||
}
|
||||
|
Reference in New Issue
Block a user