// Command zfs-restore is a simple CLI tool for restoring ZFS snapshots from a backup server. package main import ( "fmt" "os" "sort" "git.ma-al.com/goc_marek/zfs/internal/restore" ) func main() { if len(os.Args) < 2 { printUsage() os.Exit(1) } // Load configuration from environment and .env file cfg := restore.LoadConfig() client := restore.New(cfg.ClientID, cfg.APIKey, cfg.ServerURL) command := os.Args[1] switch command { case "list", "ls": // List available snapshots snapshots, err := client.ListSnapshots() if err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) } client.DisplaySnapshots(snapshots) case "restore": // Restore snapshot - can use number or "latest" keyword if len(os.Args) < 3 { fmt.Println("Usage: zfs-restore restore [--force]") fmt.Println("\nExamples:") fmt.Println(" zfs-restore restore 1 tank/restored") fmt.Println(" zfs-restore restore latest tank/restored") fmt.Println(" zfs-restore restore latest tank/restored --force") os.Exit(1) } snapshots, err := client.ListSnapshots() if err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) } // Sort by timestamp (newest first) sort.Slice(snapshots, func(i, j int) bool { return snapshots[i].Timestamp.After(snapshots[j].Timestamp) }) if len(snapshots) == 0 { fmt.Println("No snapshots available. Run 'zfs-restore list' first.") os.Exit(1) } snapshotArg := os.Args[2] var snapshot *restore.SnapshotMetadata if snapshotArg == "latest" { snapshot = snapshots[0] fmt.Printf("→ Restoring latest snapshot from %s\n", snapshot.Timestamp.Format("2006-01-02 15:04:05")) } else { var snapNum int fmt.Sscanf(snapshotArg, "%d", &snapNum) if snapNum < 1 || snapNum > len(snapshots) { fmt.Printf("Invalid snapshot number. Use 'zfs-restore list' to see available snapshots.\n") os.Exit(1) } snapshot = snapshots[snapNum-1] } // Get target dataset (either from args or prompt) targetDataset := "" force := false for i, arg := range os.Args { if arg == "--force" { force = true } if arg != "restore" && arg != snapshotArg && arg != "--force" && targetDataset == "" && i > 2 && arg != os.Args[0] { targetDataset = arg } } if targetDataset == "" { fmt.Printf("Target dataset: ") fmt.Scanln(&targetDataset) } if targetDataset == "" { fmt.Println("Error: target dataset is required") os.Exit(1) } if err := client.RestoreSnapshot(snapshot, targetDataset, force); err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) } case "help", "-h", "--help": printUsage() default: fmt.Printf("Unknown command: %s\n", command) printUsage() os.Exit(1) } } func printUsage() { fmt.Println("ZFS Snapshot Restore Tool - Simple Version") fmt.Println("\nUsage: zfs-restore [command]") fmt.Println("\nCommands:") fmt.Println(" list - List available snapshots") fmt.Println(" restore <#|latest> [--force] - Restore snapshot to ZFS") fmt.Println(" help - Show this help message") fmt.Println("\nQuick Examples:") fmt.Println(" zfs-restore list - See available backups") fmt.Println(" zfs-restore restore latest tank/data - Restore most recent backup") fmt.Println(" zfs-restore restore 1 tank/restored - Restore snapshot #1") fmt.Println("\nEnvironment Variables (can be set in .env file):") fmt.Println(" CLIENT_ID - Client identifier (default: client1)") fmt.Println(" API_KEY - API key for authentication (default: secret123)") fmt.Println(" SERVER_URL - Backup server URL (default: http://localhost:8080)") }