Add option to list storage
This commit is contained in:
@@ -160,18 +160,20 @@ proxmox-cloud-image -batch batch.txt
|
||||
| `-image-url` | - | URL cloud image (required) |
|
||||
| `-vm-name` | cloud-vm | Nama template |
|
||||
| `-vm-id` | 0 | Template ID (0 = auto-find dari 10000+) |
|
||||
| `-storage` | local-lvm | Nama storage Proxmox |
|
||||
| `-storage` | auto-detect | Nama storage Proxmox (auto-detect jika kosong) |
|
||||
| `-memory` | 2048 | Memory dalam MB |
|
||||
| `-cores` | 2 | Jumlah CPU cores |
|
||||
| `-disk-size` | 20G | Ukuran disk |
|
||||
| `-bridge` | vmbr0 | Network bridge |
|
||||
| `-vlan-tag` | 0 | VLAN tag (0 = no VLAN) |
|
||||
| `-guest-agent` | false | Enable QEMU guest agent |
|
||||
| `-firewall` | false | Enable firewall |
|
||||
| `-ssh-key` | - | Path ke SSH public key |
|
||||
| `-proxmox-host` | - | IP/hostname Proxmox (required) |
|
||||
| `-proxmox-user` | root@pam | Proxmox user |
|
||||
| `-proxmox-pass` | - | Proxmox password |
|
||||
| `-guest-agent` | false | Enable QEMU Guest Agent |
|
||||
| `-firewall` | false | Enable Proxmox firewall |
|
||||
| `-list-storage` | - | List semua storage yang tersedia |
|
||||
| `-ls` | - | Shorthand untuk `-list-storage` |
|
||||
|
||||
## How It Works
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@@ -2,4 +2,4 @@ module github.com/othman/proxmox-cloud-image
|
||||
|
||||
go 1.22.2
|
||||
|
||||
require gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
require gopkg.in/yaml.v3 v3.0.1
|
||||
|
||||
1
go.sum
1
go.sum
@@ -1,3 +1,4 @@
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
22
main.go
22
main.go
@@ -28,13 +28,16 @@ func main() {
|
||||
config := &Config{}
|
||||
var configFile string
|
||||
var batchFile string
|
||||
var listStorage bool
|
||||
|
||||
flag.StringVar(&configFile, "config", "", "Config file path (YAML)")
|
||||
flag.StringVar(&batchFile, "batch", "", "Batch file with multiple config paths (one per line)")
|
||||
flag.BoolVar(&listStorage, "list-storage", false, "List available storage on Proxmox host")
|
||||
flag.BoolVar(&listStorage, "ls", false, "List available storage on Proxmox host (shorthand)")
|
||||
flag.StringVar(&config.ImageURL, "image-url", "", "Cloud image URL to download")
|
||||
flag.StringVar(&config.VMName, "vm-name", "cloud-vm", "VM name")
|
||||
flag.IntVar(&config.VMID, "vm-id", 0, "VM ID (0 = auto-find from 10000+)")
|
||||
flag.StringVar(&config.Storage, "storage", "local-lvm", "Proxmox storage name")
|
||||
flag.StringVar(&config.Storage, "storage", "", "Proxmox storage name (auto-detect if empty)")
|
||||
flag.IntVar(&config.Memory, "memory", 2048, "Memory in MB")
|
||||
flag.IntVar(&config.Cores, "cores", 2, "CPU cores")
|
||||
flag.StringVar(&config.DiskSize, "disk-size", "20G", "Disk size (e.g., 20G)")
|
||||
@@ -44,9 +47,24 @@ func main() {
|
||||
flag.StringVar(&config.ProxmoxHost, "proxmox-host", "", "Proxmox host (e.g., 192.168.1.100)")
|
||||
flag.StringVar(&config.ProxmoxUser, "proxmox-user", "root@pam", "Proxmox user")
|
||||
flag.StringVar(&config.ProxmoxPass, "proxmox-pass", "", "Proxmox password")
|
||||
flag.BoolVar(&config.GuestAgent, "guest-agent", false, "Enable QEMU guest agent")
|
||||
flag.BoolVar(&config.Firewall, "firewall", false, "Enable firewall")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
// Handle storage listing
|
||||
if listStorage || flag.Lookup("ls").Value.(flag.Getter).Get().(bool) {
|
||||
if config.ProxmoxHost == "" {
|
||||
fmt.Println("Error: -proxmox-host is required for storage listing")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := listAvailableStorage(config); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error listing storage: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Batch mode
|
||||
if batchFile != "" {
|
||||
if err := runBatch(batchFile); err != nil {
|
||||
@@ -56,8 +74,6 @@ func main() {
|
||||
fmt.Println("\nAll templates created successfully!")
|
||||
return
|
||||
}
|
||||
|
||||
// Single config mode
|
||||
if configFile != "" {
|
||||
if err := loadConfigFile(configFile, config); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error loading config file: %v\n", err)
|
||||
|
||||
61
proxmox.go
61
proxmox.go
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -236,3 +237,63 @@ func createProxmoxVM(config *Config) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func listAvailableStorage(config *Config) error {
|
||||
fmt.Printf("Detecting available storage on %s...\n", config.ProxmoxHost)
|
||||
|
||||
sshCmd := func(args ...string) *exec.Cmd {
|
||||
fullArgs := []string{
|
||||
"-o", "StrictHostKeyChecking=no",
|
||||
"-o", "UserKnownHostsFile=/dev/null",
|
||||
fmt.Sprintf("%s@%s", strings.Split(config.ProxmoxUser, "@")[0], config.ProxmoxHost),
|
||||
}
|
||||
fullArgs = append(fullArgs, args...)
|
||||
return exec.Command("ssh", fullArgs...)
|
||||
}
|
||||
|
||||
cmd := sshCmd("pvesm", "status", "--output-format", "json")
|
||||
var stdout bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to get storage status: %w", err)
|
||||
}
|
||||
|
||||
// Parse JSON output
|
||||
var storageList []map[string]interface{}
|
||||
if err := json.Unmarshal(stdout.Bytes(), &storageList); err != nil {
|
||||
return fmt.Errorf("failed to parse storage status: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("\nAvailable storage:")
|
||||
fmt.Println("================")
|
||||
|
||||
found := false
|
||||
for _, storage := range storageList {
|
||||
nameVal, ok := storage["storage"]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
name, _ := nameVal.(string)
|
||||
|
||||
typeVal, _ := storage["type"]
|
||||
typeStr, _ := typeVal.(string)
|
||||
|
||||
activeVal, _ := storage["active"]
|
||||
activeFloat, _ := activeVal.(float64)
|
||||
|
||||
if activeFloat == 1 {
|
||||
fmt.Printf("- %s (%s) - ACTIVE\n", name, typeStr)
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
fmt.Println("No active storage found!")
|
||||
fmt.Println("\nManual check:")
|
||||
fmt.Println(" ssh root@your-proxmox 'pvesm status'")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user