feat: реализована новая логика получения machine_uid для QEMU и LXC
- Для QEMU VM: получение UUID из конфигурации (uuid, smbios1 uuid) с fallback на machine_id - Для LXC контейнеров: получение machine-id через pct exec (запущенные) или чтение из rootfs (остановленные) - Добавлены функции getLXCMachineIDViaExec и getLXCMachineIDFromRootfs - Улучшена логика fallback для случаев когда UUID недоступен - Все machine_uid генерируются как SHA256[:16] для консистентности - Протестировано на реальных VM и контейнерах
This commit is contained in:
parent
96b841d6c8
commit
b23d724bea
@ -279,24 +279,8 @@ func processQEMUVM(vm VM, nodeName, clusterUID, nodeUID string) map[string]any {
|
||||
machineID = "unknown"
|
||||
}
|
||||
|
||||
// Для QEMU VM пытаемся получить UUID из smbios1
|
||||
var machineUID string
|
||||
if smbiosUUID := getString(config, "smbios1"); smbiosUUID != "" {
|
||||
// Извлекаем UUID из строки типа "uuid=5325693e-271b-47ed-95c2-3a2cf42f4886"
|
||||
if strings.Contains(smbiosUUID, "uuid=") {
|
||||
parts := strings.Split(smbiosUUID, "uuid=")
|
||||
if len(parts) > 1 {
|
||||
uuid := strings.TrimSpace(parts[1])
|
||||
machineUID = generateMachineUID(uuid)
|
||||
} else {
|
||||
machineUID = generateMachineUID(machineID)
|
||||
}
|
||||
} else {
|
||||
machineUID = generateMachineUID(machineID)
|
||||
}
|
||||
} else {
|
||||
machineUID = generateMachineUID(machineID)
|
||||
}
|
||||
// Генерируем machine_uid
|
||||
machineUID := generateMachineUID("QEMU", vmidStr, config)
|
||||
|
||||
// Создаем структуру VM
|
||||
vmData := map[string]any{
|
||||
@ -396,7 +380,7 @@ func processLXCContainer(ct VM, nodeName, clusterUID, nodeUID string) map[string
|
||||
}
|
||||
|
||||
// Генерируем machine_uid
|
||||
machineUID := generateMachineUID(machineID)
|
||||
machineUID := generateMachineUID("LXC", vmidStr, config)
|
||||
|
||||
// Создаем структуру контейнера
|
||||
ctData := map[string]any{
|
||||
@ -573,13 +557,123 @@ func generateNodeUID(clusterUUID, nodeID string) string {
|
||||
return hex.EncodeToString(hash[:])[:16]
|
||||
}
|
||||
|
||||
// generateMachineUID создает уникальный ID машины на основе machine_id
|
||||
func generateMachineUID(machineID string) string {
|
||||
if machineID == "" {
|
||||
machineID = "unknown-machine-id"
|
||||
// generateMachineUID генерирует уникальный ID машины для QEMU и LXC
|
||||
func generateMachineUID(vmType, vmid string, config map[string]interface{}) string {
|
||||
if vmType == "QEMU" {
|
||||
return generateQEMUMachineUID(vmid, config)
|
||||
} else if vmType == "LXC" {
|
||||
return generateLXCMachineUID(vmid, config)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// generateQEMUMachineUID генерирует machine_uid для QEMU VM
|
||||
func generateQEMUMachineUID(vmid string, config map[string]interface{}) string {
|
||||
// 1. Пытаемся получить uuid из конфигурации
|
||||
if uuid, ok := config["uuid"].(string); ok && uuid != "" {
|
||||
hash := sha256.Sum256([]byte(uuid))
|
||||
return hex.EncodeToString(hash[:])[:16]
|
||||
}
|
||||
|
||||
// 2. Пытаемся получить smbios1 uuid из конфигурации
|
||||
if smbios1, ok := config["smbios1"].(string); ok && smbios1 != "" {
|
||||
// Парсим smbios1 для поиска uuid
|
||||
if parsed := parseKeyValueString(smbios1); parsed != nil {
|
||||
if uuid, exists := parsed["uuid"]; exists {
|
||||
if uuidStr, ok := uuid.(string); ok && uuidStr != "" {
|
||||
hash := sha256.Sum256([]byte(uuidStr))
|
||||
return hex.EncodeToString(hash[:])[:16]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fallback: используем machine_id
|
||||
if machineID, ok := config["machine_id"].(string); ok && machineID != "" {
|
||||
hash := sha256.Sum256([]byte(machineID))
|
||||
return hex.EncodeToString(hash[:])[:16]
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// generateLXCMachineUID генерирует machine_uid для LXC контейнера
|
||||
func generateLXCMachineUID(vmid string, config map[string]interface{}) string {
|
||||
// 1. Пытаемся получить machine-id из конфигурации
|
||||
if machineID, ok := config["machine_id"].(string); ok && machineID != "" {
|
||||
hash := sha256.Sum256([]byte(machineID))
|
||||
return hex.EncodeToString(hash[:])[:16]
|
||||
}
|
||||
|
||||
// 2. Пытаемся получить machine-id через pct exec (если контейнер запущен)
|
||||
if machineID := getLXCMachineIDViaExec(vmid); machineID != "" {
|
||||
hash := sha256.Sum256([]byte(machineID))
|
||||
return hex.EncodeToString(hash[:])[:16]
|
||||
}
|
||||
|
||||
// 3. Пытаемся прочитать machine-id из rootfs (если контейнер остановлен)
|
||||
if machineID := getLXCMachineIDFromRootfs(vmid); machineID != "" {
|
||||
hash := sha256.Sum256([]byte(machineID))
|
||||
return hex.EncodeToString(hash[:])[:16]
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// getLXCMachineIDViaExec получает machine-id через pct exec (для запущенных контейнеров)
|
||||
func getLXCMachineIDViaExec(vmid string) string {
|
||||
cmd := exec.Command("pct", "exec", vmid, "--", "cat", "/etc/machine-id")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
debugLog("Failed to get machine-id via pct exec for LXC %s: %v", vmid, err)
|
||||
return ""
|
||||
}
|
||||
|
||||
machineID := strings.TrimSpace(string(output))
|
||||
if machineID == "" {
|
||||
debugLog("Empty machine-id from pct exec for LXC %s", vmid)
|
||||
return ""
|
||||
}
|
||||
|
||||
debugLog("Successfully got machine-id via pct exec for LXC %s: %s", vmid, machineID)
|
||||
return machineID
|
||||
}
|
||||
|
||||
// getLXCMachineIDFromRootfs читает machine-id из rootfs (для остановленных контейнеров)
|
||||
func getLXCMachineIDFromRootfs(vmid string) string {
|
||||
// Пробуем разные возможные пути
|
||||
paths := []string{
|
||||
fmt.Sprintf("/var/lib/lxc/%s/rootfs/etc/machine-id", vmid),
|
||||
fmt.Sprintf("/rpool/data/subvol-%s-disk-0/etc/machine-id", vmid),
|
||||
fmt.Sprintf("/var/lib/lxc/%s/rootfs/var/lib/dbus/machine-id", vmid),
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
if machineID := readMachineIDFromFile(path); machineID != "" {
|
||||
debugLog("Successfully read machine-id from %s for LXC %s: %s", path, vmid, machineID)
|
||||
return machineID
|
||||
}
|
||||
}
|
||||
|
||||
debugLog("Failed to read machine-id from rootfs for LXC %s", vmid)
|
||||
return ""
|
||||
}
|
||||
|
||||
// readMachineIDFromFile читает machine-id из файла
|
||||
func readMachineIDFromFile(path string) string {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
debugLog("Failed to read file %s: %v", path, err)
|
||||
return ""
|
||||
}
|
||||
|
||||
machineID := strings.TrimSpace(string(data))
|
||||
if machineID == "" {
|
||||
debugLog("Empty machine-id in file %s", path)
|
||||
return ""
|
||||
}
|
||||
|
||||
return machineID
|
||||
}
|
||||
|
||||
// getString извлекает строку из map[string]interface{}
|
||||
|
Loading…
x
Reference in New Issue
Block a user