From 5182460b69e61e9db85b89b802733638371d4a46 Mon Sep 17 00:00:00 2001 From: Othman Hendy Suseno Date: Fri, 14 Nov 2025 21:25:40 +0700 Subject: [PATCH] Fix disk path parsing for directory storage- Parse actual disk path from qm importdisk output- Support both LVM (local-lvm:vm-X-disk-0) and directory (local:VMID/vm-X-disk-0.raw) storage- Fix 'unable to parse directory volume name' error --- proxmox.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/proxmox.go b/proxmox.go index 566170f..fda166e 100644 --- a/proxmox.go +++ b/proxmox.go @@ -123,17 +123,64 @@ func createProxmoxVM(config *Config) error { } fmt.Println("Creating VM and converting to template...") + + // Create VM + createCmd := []string{"qm", "create", fmt.Sprintf("%d", config.VMID), + "--name", config.VMName, + "--memory", fmt.Sprintf("%d", config.Memory), + "--cores", fmt.Sprintf("%d", config.Cores), + "--net0", buildNetworkConfig(config), + } + + fmt.Printf("Running: %s\n", strings.Join(createCmd, " ")) + cmd := sshCmd(createCmd...) + if err := cmd.Run(); err != nil { + return fmt.Errorf("failed to create VM: %w", err) + } + + // Import disk and capture output to get actual disk path + importCmd := []string{"qm", "importdisk", fmt.Sprintf("%d", config.VMID), remotePath, config.Storage} + fmt.Printf("Running: %s\n", strings.Join(importCmd, " ")) + + cmd = sshCmd(importCmd...) + var importOut bytes.Buffer + cmd.Stdout = &importOut + cmd.Stderr = &importOut + + if err := cmd.Run(); err != nil { + fmt.Println(importOut.String()) + return fmt.Errorf("failed to import disk: %w", err) + } + + output := importOut.String() + fmt.Println(output) + + // Parse disk path from output + // Example: "unused0: successfully imported disk 'local:10001/vm-10001-disk-0.raw'" + var diskPath string + lines := strings.Split(output, "\n") + for _, line := range lines { + if strings.Contains(line, "successfully imported disk") { + start := strings.Index(line, "'") + end := strings.LastIndex(line, "'") + if start != -1 && end != -1 && end > start { + diskPath = line[start+1 : end] + break + } + } + } + + if diskPath == "" { + return fmt.Errorf("failed to parse disk path from importdisk output") + } + + fmt.Printf("Imported disk path: %s\n", diskPath) + + // Configure VM with the actual disk path commands := [][]string{ - {"qm", "create", fmt.Sprintf("%d", config.VMID), - "--name", config.VMName, - "--memory", fmt.Sprintf("%d", config.Memory), - "--cores", fmt.Sprintf("%d", config.Cores), - "--net0", buildNetworkConfig(config), - }, - {"qm", "importdisk", fmt.Sprintf("%d", config.VMID), remotePath, config.Storage}, {"qm", "set", fmt.Sprintf("%d", config.VMID), "--scsihw", "virtio-scsi-pci", - "--scsi0", fmt.Sprintf("%s:vm-%d-disk-0", config.Storage, config.VMID), + "--scsi0", diskPath, }, {"qm", "set", fmt.Sprintf("%d", config.VMID), "--ide2", fmt.Sprintf("%s:cloudinit", config.Storage),