package host import ( "fmt" "github.com/bdw/ship/internal/ssh" "github.com/bdw/ship/internal/state" "github.com/spf13/cobra" ) var statusCmd = &cobra.Command{ Use: "status", Short: "Show VPS health (uptime, disk, memory)", RunE: runStatus, } func runStatus(cmd *cobra.Command, args []string) error { st, err := state.Load() if err != nil { return fmt.Errorf("error loading state: %w", err) } host, _ := cmd.Flags().GetString("host") if host == "" { host = st.GetDefaultHost() } if host == "" { return fmt.Errorf("--host is required (no default host set)") } fmt.Printf("Connecting to %s...\n\n", host) client, err := ssh.Connect(host) if err != nil { return fmt.Errorf("error connecting to VPS: %w", err) } defer client.Close() 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() 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() 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() 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() 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() fmt.Println("SERVICES") if output, err := client.Run("systemctl is-active caddy 2>/dev/null && echo ' Caddy: active' || echo ' Caddy: inactive'"); err == nil { if output == "active\n" { fmt.Println(" Caddy: active") } else { fmt.Println(" Caddy: inactive") } } 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) } return nil }