summaryrefslogtreecommitdiffstats
path: root/cmd/deploy/remove.go
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-01-23 21:52:50 -0800
committerbndw <ben@bdw.to>2026-01-23 21:52:50 -0800
commit87752492d0dc7df3cf78011d5ce315a3eb0cad51 (patch)
tree76843c127fece33f5c28dd7bd533044043478825 /cmd/deploy/remove.go
parent57eb67df265a7a6bb544cde83a3be5eadf53fdf2 (diff)
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.
Diffstat (limited to 'cmd/deploy/remove.go')
-rw-r--r--cmd/deploy/remove.go83
1 files changed, 83 insertions, 0 deletions
diff --git a/cmd/deploy/remove.go b/cmd/deploy/remove.go
new file mode 100644
index 0000000..5a98bf3
--- /dev/null
+++ b/cmd/deploy/remove.go
@@ -0,0 +1,83 @@
1package main
2
3import (
4 "fmt"
5
6 "github.com/bdw/deploy/internal/ssh"
7 "github.com/bdw/deploy/internal/state"
8 "github.com/spf13/cobra"
9)
10
11var removeCmd = &cobra.Command{
12 Use: "remove <app>",
13 Aliases: []string{"rm"},
14 Short: "Remove a deployment",
15 Args: cobra.ExactArgs(1),
16 RunE: runRemove,
17}
18
19func runRemove(cmd *cobra.Command, args []string) error {
20 name := args[0]
21
22 st, err := state.Load()
23 if err != nil {
24 return fmt.Errorf("error loading state: %w", err)
25 }
26
27 host := hostFlag
28 if host == "" {
29 host = st.GetDefaultHost()
30 }
31
32 if host == "" {
33 return fmt.Errorf("--host is required")
34 }
35
36 app, err := st.GetApp(host, name)
37 if err != nil {
38 return err
39 }
40
41 fmt.Printf("Removing deployment: %s\n", name)
42
43 client, err := ssh.Connect(host)
44 if err != nil {
45 return fmt.Errorf("error connecting to VPS: %w", err)
46 }
47 defer client.Close()
48
49 if app.Type == "app" {
50 fmt.Println("-> Stopping service...")
51 client.RunSudo(fmt.Sprintf("systemctl stop %s", name))
52 client.RunSudo(fmt.Sprintf("systemctl disable %s", name))
53
54 client.RunSudo(fmt.Sprintf("rm -f /etc/systemd/system/%s.service", name))
55 client.RunSudo("systemctl daemon-reload")
56
57 client.RunSudo(fmt.Sprintf("rm -f /usr/local/bin/%s", name))
58 client.RunSudo(fmt.Sprintf("rm -rf /var/lib/%s", name))
59 client.RunSudo(fmt.Sprintf("rm -f /etc/deploy/env/%s.env", name))
60 client.RunSudo(fmt.Sprintf("userdel %s", name))
61 } else {
62 fmt.Println("-> Removing files...")
63 client.RunSudo(fmt.Sprintf("rm -rf /var/www/%s", name))
64 }
65
66 fmt.Println("-> Removing Caddy config...")
67 client.RunSudo(fmt.Sprintf("rm -f /etc/caddy/sites-enabled/%s.caddy", name))
68
69 fmt.Println("-> Reloading Caddy...")
70 if _, err := client.RunSudo("systemctl reload caddy"); err != nil {
71 fmt.Printf("Warning: Error reloading Caddy: %v\n", err)
72 }
73
74 if err := st.RemoveApp(host, name); err != nil {
75 return fmt.Errorf("error updating state: %w", err)
76 }
77 if err := st.Save(); err != nil {
78 return fmt.Errorf("error saving state: %w", err)
79 }
80
81 fmt.Println("Deployment removed successfully")
82 return nil
83}