From 87752492d0dc7df3cf78011d5ce315a3eb0cad51 Mon Sep 17 00:00:00 2001 From: bndw Date: Fri, 23 Jan 2026 21:52:50 -0800 Subject: Restructure CLI with Cobra Replace custom switch-based routing with Cobra for cleaner command hierarchy. Reorganize commands into logical groups: - Root command handles deployment (--binary, --static, --domain, etc.) - App management at top level: list, logs, status, restart, remove - env subcommand group: list, set, unset - host subcommand group: init, status, update, ssh - Standalone: ui (renamed from webui), version Add version command with ldflags support for build info. --- cmd/deploy/vps.go | 229 ------------------------------------------------------ 1 file changed, 229 deletions(-) delete mode 100644 cmd/deploy/vps.go (limited to 'cmd/deploy/vps.go') diff --git a/cmd/deploy/vps.go b/cmd/deploy/vps.go deleted file mode 100644 index bd6278b..0000000 --- a/cmd/deploy/vps.go +++ /dev/null @@ -1,229 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "os/exec" - - "github.com/bdw/deploy/internal/ssh" - "github.com/bdw/deploy/internal/state" -) - -func runVPS(args []string) { - fs := flag.NewFlagSet("vps", flag.ExitOnError) - host := fs.String("host", "", "VPS host (SSH config alias or user@host)") - fs.Parse(args) - - // Load state - st, err := state.Load() - if err != nil { - fmt.Fprintf(os.Stderr, "Error loading state: %v\n", err) - os.Exit(1) - } - - // Get host from flag or state default - if *host == "" { - *host = st.GetDefaultHost() - } - - if *host == "" { - fmt.Fprintf(os.Stderr, "Error: --host is required (no default host set)\n") - fs.Usage() - os.Exit(1) - } - - fmt.Printf("Connecting to %s...\n\n", *host) - - // Connect to VPS - client, err := ssh.Connect(*host) - if err != nil { - fmt.Fprintf(os.Stderr, "Error connecting to VPS: %v\n", err) - os.Exit(1) - } - defer client.Close() - - // Uptime - fmt.Println("UPTIME") - if output, err := client.Run("uptime -p"); err == nil { - fmt.Printf(" %s", output) - } - if output, err := client.Run("uptime -s"); err == nil { - fmt.Printf(" Since: %s", output) - } - fmt.Println() - - // Load average - fmt.Println("LOAD") - if output, err := client.Run("cat /proc/loadavg | awk '{print $1, $2, $3}'"); err == nil { - fmt.Printf(" 1m, 5m, 15m: %s", output) - } - fmt.Println() - - // Memory - fmt.Println("MEMORY") - if output, err := client.Run("free -h | awk 'NR==2 {print \" Used: \" $3 \" / \" $2}'"); err == nil { - fmt.Print(output) - } - if output, err := client.Run("free -h | awk 'NR==2 {printf \" Available: %s\\n\", $7}'"); err == nil { - fmt.Print(output) - } - fmt.Println() - - // Disk - fmt.Println("DISK") - if output, err := client.Run("df -h / | awk 'NR==2 {print \" Used: \" $3 \" / \" $2 \" (\" $5 \")\"}'"); err == nil { - fmt.Print(output) - } - if output, err := client.Run("df -h / | awk 'NR==2 {print \" Available: \" $4}'"); err == nil { - fmt.Print(output) - } - fmt.Println() - - // Updates available - fmt.Println("UPDATES") - if output, err := client.Run("[ -f /var/lib/update-notifier/updates-available ] && cat /var/lib/update-notifier/updates-available | head -2 || echo ' (update info not available)'"); err == nil { - fmt.Print(output) - } - fmt.Println() - - // Services - fmt.Println("SERVICES") - if output, err := client.Run("systemctl is-active caddy 2>/dev/null && echo ' Caddy: active' || echo ' Caddy: inactive'"); err == nil { - // Parse the output - if output == "active\n" { - fmt.Println(" Caddy: active") - } else { - fmt.Println(" Caddy: inactive") - } - } - - // Count deployed apps that are running - hostState := st.GetHost(*host) - if hostState != nil && len(hostState.Apps) > 0 { - activeCount := 0 - for name, app := range hostState.Apps { - if app.Type == "app" { - if output, err := client.Run(fmt.Sprintf("systemctl is-active %s 2>/dev/null", name)); err == nil && output == "active\n" { - activeCount++ - } - } - } - appCount := 0 - for _, app := range hostState.Apps { - if app.Type == "app" { - appCount++ - } - } - fmt.Printf(" Deployed apps: %d/%d active\n", activeCount, appCount) - } -} - -func runUpdate(args []string) { - fs := flag.NewFlagSet("vps-update", flag.ExitOnError) - host := fs.String("host", "", "VPS host (SSH config alias or user@host)") - yes := fs.Bool("y", false, "Skip confirmation prompt") - fs.Parse(args) - - // Load state - st, err := state.Load() - if err != nil { - fmt.Fprintf(os.Stderr, "Error loading state: %v\n", err) - os.Exit(1) - } - - // Get host from flag or state default - if *host == "" { - *host = st.GetDefaultHost() - } - - if *host == "" { - fmt.Fprintf(os.Stderr, "Error: --host is required (no default host set)\n") - fs.Usage() - os.Exit(1) - } - - // Confirm unless -y flag is set - if !*yes { - fmt.Printf("This will run apt update && apt upgrade on %s\n", *host) - fmt.Print("Continue? [y/N]: ") - var response string - fmt.Scanln(&response) - if response != "y" && response != "Y" { - fmt.Println("Aborted.") - return - } - } - - fmt.Printf("Connecting to %s...\n", *host) - - // Connect to VPS - client, err := ssh.Connect(*host) - if err != nil { - fmt.Fprintf(os.Stderr, "Error connecting to VPS: %v\n", err) - os.Exit(1) - } - defer client.Close() - - // Run apt update - fmt.Println("\n→ Running apt update...") - if err := client.RunSudoStream("apt update"); err != nil { - fmt.Fprintf(os.Stderr, "Error running apt update: %v\n", err) - os.Exit(1) - } - - // Run apt upgrade - fmt.Println("\n→ Running apt upgrade...") - if err := client.RunSudoStream("DEBIAN_FRONTEND=noninteractive apt upgrade -y"); err != nil { - fmt.Fprintf(os.Stderr, "Error running apt upgrade: %v\n", err) - os.Exit(1) - } - - // Check if reboot is required - fmt.Println() - if output, err := client.Run("[ -f /var/run/reboot-required ] && echo 'yes' || echo 'no'"); err == nil { - if output == "yes\n" { - fmt.Println("Note: A reboot is required to complete the update.") - } - } - - fmt.Println("āœ“ Update complete") -} - -func runSSH(args []string) { - fs := flag.NewFlagSet("vps-ssh", flag.ExitOnError) - host := fs.String("host", "", "VPS host (SSH config alias or user@host)") - fs.Parse(args) - - // Load state - st, err := state.Load() - if err != nil { - fmt.Fprintf(os.Stderr, "Error loading state: %v\n", err) - os.Exit(1) - } - - // Get host from flag or state default - if *host == "" { - *host = st.GetDefaultHost() - } - - if *host == "" { - fmt.Fprintf(os.Stderr, "Error: --host is required (no default host set)\n") - fs.Usage() - os.Exit(1) - } - - // Launch interactive SSH session - cmd := exec.Command("ssh", *host) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - if err := cmd.Run(); err != nil { - if exitErr, ok := err.(*exec.ExitError); ok { - os.Exit(exitErr.ExitCode()) - } - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) - } -} -- cgit v1.2.3