diff --git a/virt-v2v/cold/entrypoint.go b/virt-v2v/cold/entrypoint.go index 46aaf6bba..752749104 100644 --- a/virt-v2v/cold/entrypoint.go +++ b/virt-v2v/cold/entrypoint.go @@ -82,18 +82,8 @@ func main() { } } -func getVmDiskPaths(domain *OvaVmconfig) []string { - var resp []string - for _, disk := range domain.Devices.Disks { - if disk.Source.File != "" { - resp = append(resp, disk.Source.File) - } - } - return resp -} - -func customizeVM(source string, xmlFilePath string) error { - domain, err := GetDomainFromXml(xmlFilePath) +func customizeVM(source string, yamlFilePath string) error { + vmConfig, err := GetVmConfigYaml(yamlFilePath) if err != nil { fmt.Printf("Error mapping xml to domain: %v\n", err) @@ -102,7 +92,7 @@ func customizeVM(source string, xmlFilePath string) error { } // Get operating system. - operatingSystem := domain.Metadata.LibOsInfo.V2VOS.ID + operatingSystem := vmConfig.OSInfo if operatingSystem == "" { fmt.Printf("Warning: no operating system found") @@ -112,15 +102,13 @@ func customizeVM(source string, xmlFilePath string) error { fmt.Printf("Operating System ID: %s\n", operatingSystem) } - // Get domain disks. - disks := getVmDiskPaths(domain) - if len(disks) == 0 { + if len(vmConfig.DiskPaths) == 0 { fmt.Printf("Warning: no V2V domain disks found") // No customization when no disks found. return nil } else { - fmt.Printf("V2V domain disks: %v\n", disks) + fmt.Printf("V2V domain disks: %v\n", vmConfig.DiskPaths) } // Customization for vSphere source. @@ -129,7 +117,7 @@ func customizeVM(source string, xmlFilePath string) error { if strings.Contains(operatingSystem, "win") { t := EmbedTool{filesystem: &scriptFS} - err = CustomizeWindows(disks, DIR, &t) + err = CustomizeWindows(vmConfig.DiskPaths, DIR, &t) if err != nil { fmt.Println("Error customizing disk image:", err) return err @@ -140,7 +128,7 @@ func customizeVM(source string, xmlFilePath string) error { if !strings.Contains(operatingSystem, "win") { t := EmbedTool{filesystem: &scriptFS} - err = CustomizeLinux(CustomizeDomainExec, disks, DIR, &t) + err = CustomizeLinux(CustomizeDomainExec, vmConfig.DiskPaths, DIR, &t) if err != nil { fmt.Println("Error customizing disk image:", err) return err diff --git a/virt-v2v/cold/xml-reader.go b/virt-v2v/cold/xml-reader.go deleted file mode 100644 index 07aadc656..000000000 --- a/virt-v2v/cold/xml-reader.go +++ /dev/null @@ -1,97 +0,0 @@ -package main - -import ( - "encoding/xml" - "fmt" - "os" -) - -type OvaVmconfig struct { - XMLName xml.Name `xml:"domain"` - Name string `xml:"name"` - OS OS `xml:"os"` - Metadata Metadata `xml:"metadata"` - Devices Devices `xml:"devices"` -} - -type OS struct { - Type OSType `xml:"type"` - Loader Loader `xml:"loader"` - Nvram Nvram `xml:"nvram"` -} - -type Metadata struct { - LibOsInfo LibOsInfo `xml:"libosinfo"` -} - -type Devices struct { - Disks []Disk `xml:"disk"` -} -type Disk struct { - Source Source `xml:"source"` -} -type Source struct { - File string `xml:"file,attr"` -} - -type LibOsInfo struct { - V2VOS V2VOS `xml:"os"` -} - -type V2VOS struct { - ID string `xml:"id,attr"` -} - -type OSType struct { - Arch string `xml:"arch,attr"` - Machine string `xml:"machine,attr"` - Content string `xml:",chardata"` -} - -type Loader struct { - Readonly string `xml:"readonly,attr"` - Type string `xml:"type,attr"` - Secure string `xml:"secure,attr"` - Path string `xml:",chardata"` -} - -type Nvram struct { - Template string `xml:"template,attr"` -} - -// ReadXMLFile reads the content of an XML []byte from the given file path. -// -// Arguments: -// - filePath (string): The path to the XML file. -// -// Returns: -// - []byte: The content of the XML file. -// - error: An error if the file cannot be read, or nil if successful. -func ReadXMLFile(filePath string) ([]byte, error) { - if filePath == "" { - return nil, fmt.Errorf("XML file path is empty") - } - - xmlData, err := os.ReadFile(filePath) - if err != nil { - return nil, fmt.Errorf("error reading XML file: %w", err) - } - - return xmlData, nil -} - -func GetDomainFromXml(xmlFilePath string) (*OvaVmconfig, error) { - xmlData, err := ReadXMLFile(xmlFilePath) - if err != nil { - fmt.Printf("Error read XML: %v\n", err) - return nil, err - } - - var xmlConf OvaVmconfig - err = xml.Unmarshal(xmlData, &xmlConf) - if err != nil { - fmt.Printf("Error unmarshalling XML: %v\n", err) - return nil, err - } - return &xmlConf, nil -} diff --git a/virt-v2v/cold/yaml-reader.go b/virt-v2v/cold/yaml-reader.go new file mode 100644 index 000000000..4bc27cae7 --- /dev/null +++ b/virt-v2v/cold/yaml-reader.go @@ -0,0 +1,73 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +type VmConfig struct { + OSInfo string + DiskPaths []string +} + +// ReadYAMLFile reads the YAML file and extracts the HostDisk paths and osinfo label. +func GetVmConfigYaml(filePath string) (*VmConfig, error) { + file, err := os.Open(filePath) + if err != nil { + return nil, fmt.Errorf("error opening YAML file: %w", err) + } + defer file.Close() + + config := &VmConfig{} + scanner := bufio.NewScanner(file) + var inLabels, inVolumes bool + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + + if line == "" || strings.HasPrefix(line, "#") { + continue + } + + if strings.HasPrefix(line, "labels:") { + inLabels = true + continue + } + + if inLabels { + if strings.HasPrefix(line, "libguestfs.org/osinfo:") { + config.OSInfo = strings.TrimSpace(strings.TrimPrefix(line, "libguestfs.org/osinfo:")) + } + if !strings.HasPrefix(line, "libguestfs.org/") { + inLabels = false + } + } + + if strings.Contains(line, "volumes:") { + inVolumes = true + continue + } + if inVolumes { + if strings.Contains(line, "hostDisk:") { + scanner.Scan() + pathLine := strings.TrimSpace(scanner.Text()) + if strings.HasPrefix(pathLine, "path:") { + pathValue := strings.TrimSpace(strings.TrimPrefix(pathLine, "path:")) + if pathValue != "" { + config.DiskPaths = append(config.DiskPaths, pathValue) + } + } + } + if strings.Contains(line, "- name:") { + inVolumes = false + } + } + } + + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("error reading YAML file: %w", err) + } + + return config, nil +}