121 lines
2.7 KiB
Go
121 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func customizeImage(config *Config) error {
|
|
fmt.Println("Customizing image...")
|
|
|
|
if err := checkDependencies(); err != nil {
|
|
return err
|
|
}
|
|
|
|
imagePath := config.ImageURL
|
|
if strings.HasSuffix(imagePath, ".qcow2") {
|
|
if err := resizeImage(imagePath, config.DiskSize); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if config.SSHKey != "" {
|
|
if err := injectSSHKey(imagePath, config.SSHKey); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if config.GuestAgent {
|
|
if err := installGuestAgent(imagePath); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
fmt.Println("Verifying customized image...")
|
|
if err := verifyImage(imagePath); err != nil {
|
|
return fmt.Errorf("customized image verification failed: %w", err)
|
|
}
|
|
fmt.Println("Customized image verification passed!")
|
|
|
|
return nil
|
|
}
|
|
|
|
func checkDependencies() error {
|
|
deps := []string{"qemu-img", "virt-customize"}
|
|
for _, dep := range deps {
|
|
if _, err := exec.LookPath(dep); err != nil {
|
|
return fmt.Errorf("required dependency '%s' not found. Please install libguestfs-tools and qemu-utils", dep)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func resizeImage(imagePath, size string) error {
|
|
fmt.Printf("Resizing image to %s...\n", size)
|
|
|
|
cmd := exec.Command("qemu-img", "resize", imagePath, size)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("failed to resize image: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func injectSSHKey(imagePath, sshKeyPath string) error {
|
|
fmt.Printf("Injecting SSH key from %s...\n", sshKeyPath)
|
|
|
|
keyData, err := os.ReadFile(sshKeyPath)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read SSH key: %w", err)
|
|
}
|
|
|
|
tmpDir := "/tmp/cloud-init-" + filepath.Base(imagePath)
|
|
os.MkdirAll(tmpDir, 0755)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
keyFile := filepath.Join(tmpDir, "authorized_keys")
|
|
if err := os.WriteFile(keyFile, keyData, 0644); err != nil {
|
|
return fmt.Errorf("failed to write SSH key: %w", err)
|
|
}
|
|
|
|
cmd := exec.Command("virt-customize",
|
|
"-a", imagePath,
|
|
"--mkdir", "/root/.ssh",
|
|
"--upload", keyFile+":/root/.ssh/authorized_keys",
|
|
"--chmod", "0600:/root/.ssh/authorized_keys",
|
|
)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("failed to inject SSH key: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func installGuestAgent(imagePath string) error {
|
|
fmt.Println("Installing QEMU Guest Agent...")
|
|
|
|
cmd := exec.Command("virt-customize",
|
|
"-a", imagePath,
|
|
"--install", "qemu-guest-agent",
|
|
"--run-command", "systemctl enable qemu-guest-agent",
|
|
)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("failed to install qemu-guest-agent: %w", err)
|
|
}
|
|
|
|
fmt.Println("QEMU Guest Agent installed and enabled!")
|
|
return nil
|
|
}
|