Add checksum verification and retry logic- Add SHA256 checksum verification for downloaded images- Add qemu-img check verification before and after operations- Add retry logic (3 attempts) for download, upload, and commands- Verify image integrity after customization- Verify uploaded image on Proxmox host before import- Auto-remove corrupted images and retry download
This commit is contained in:
76
proxmox.go
76
proxmox.go
@@ -82,11 +82,44 @@ func createProxmoxVM(config *Config) error {
|
||||
remotePath := fmt.Sprintf("/tmp/%s", imageName)
|
||||
|
||||
fmt.Println("Uploading image to Proxmox host...")
|
||||
cmd := scpCmd(config.ImageURL, remotePath)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to upload image: %w", err)
|
||||
maxRetries := 3
|
||||
var uploadErr error
|
||||
for attempt := 1; attempt <= maxRetries; attempt++ {
|
||||
if attempt > 1 {
|
||||
fmt.Printf("Retry upload attempt %d/%d...\n", attempt, maxRetries)
|
||||
}
|
||||
|
||||
cmd := scpCmd(config.ImageURL, remotePath)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
uploadErr = cmd.Run()
|
||||
|
||||
if uploadErr == nil {
|
||||
fmt.Println("Upload completed! Verifying uploaded image...")
|
||||
|
||||
verifyCmd := sshCmd("qemu-img", "check", remotePath)
|
||||
var verifyOut bytes.Buffer
|
||||
verifyCmd.Stdout = &verifyOut
|
||||
verifyCmd.Stderr = &verifyOut
|
||||
|
||||
if err := verifyCmd.Run(); err != nil {
|
||||
fmt.Printf("Remote image verification failed: %s\n", verifyOut.String())
|
||||
if attempt < maxRetries {
|
||||
fmt.Println("Re-uploading...")
|
||||
sshCmd("rm", "-f", remotePath).Run()
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("uploaded image verification failed after %d attempts", maxRetries)
|
||||
}
|
||||
|
||||
fmt.Println("Remote image verification passed!")
|
||||
break
|
||||
}
|
||||
|
||||
if attempt == maxRetries {
|
||||
return fmt.Errorf("failed to upload image after %d attempts: %w", maxRetries, uploadErr)
|
||||
}
|
||||
fmt.Printf("Upload failed: %v\n", uploadErr)
|
||||
}
|
||||
|
||||
fmt.Println("Creating VM and converting to template...")
|
||||
@@ -119,20 +152,35 @@ func createProxmoxVM(config *Config) error {
|
||||
|
||||
for _, cmdArgs := range commands {
|
||||
fmt.Printf("Running: %s\n", strings.Join(cmdArgs, " "))
|
||||
cmd := sshCmd(cmdArgs...)
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
var cmdErr error
|
||||
for attempt := 1; attempt <= maxRetries; attempt++ {
|
||||
if attempt > 1 {
|
||||
fmt.Printf("Retry command attempt %d/%d...\n", attempt, maxRetries)
|
||||
}
|
||||
|
||||
cmd := sshCmd(cmdArgs...)
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
cmdErr = cmd.Run()
|
||||
|
||||
if cmdErr == nil {
|
||||
if stdout.Len() > 0 {
|
||||
fmt.Println(stdout.String())
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Println(stdout.String())
|
||||
fmt.Println(stderr.String())
|
||||
return fmt.Errorf("failed to execute command '%s': %w", strings.Join(cmdArgs, " "), err)
|
||||
}
|
||||
|
||||
if stdout.Len() > 0 {
|
||||
fmt.Println(stdout.String())
|
||||
if attempt == maxRetries {
|
||||
return fmt.Errorf("failed to execute command '%s' after %d attempts: %w", strings.Join(cmdArgs, " "), maxRetries, cmdErr)
|
||||
}
|
||||
|
||||
fmt.Printf("Command failed: %v\n", cmdErr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user