66 "path/filepath"
77 "strings"
88
9+ "github.com/acmore/okdev/internal/config"
910 "github.com/acmore/okdev/internal/session"
1011 "github.com/spf13/cobra"
1112 apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -19,21 +20,31 @@ func newDownCmd(opts *Options) *cobra.Command {
1920 Use : "down" ,
2021 Short : "Delete a dev session pod" ,
2122 RunE : func (cmd * cobra.Command , args []string ) error {
23+ ui := newUpUI (cmd .OutOrStdout (), cmd .ErrOrStderr ())
24+ ui .section ("Validate" )
2225 cfg , ns , err := loadConfigAndNamespace (opts )
2326 if err != nil {
2427 return err
2528 }
29+ cfgPath , pathErr := config .ResolvePath (opts .ConfigPath )
30+ if pathErr == nil {
31+ ui .stepDone ("config" , cfgPath )
32+ }
2633 sn , err := resolveSessionNameForUpDown (opts , cfg , ns )
2734 if err != nil {
2835 return err
2936 }
37+ ui .stepDone ("session" , sn )
38+ ui .stepDone ("namespace" , ns )
3039 k := newKubeClient (opts )
3140 if err := ensureSessionOwnership (opts , k , ns , sn , false ); err != nil {
3241 return err
3342 }
43+ ui .stepDone ("ownership" , "ok" )
3444 ctx , cancel := defaultContext ()
3545 defer cancel ()
3646 if dryRun {
47+ ui .section ("Dry Run" )
3748 fmt .Fprintf (cmd .OutOrStdout (), "DRY RUN: session=%s namespace=%s\n " , sn , ns )
3849 fmt .Fprintf (cmd .OutOrStdout (), "- would delete pod/%s\n " , podName (sn ))
3950 if deletePVC && cfg .Spec .Workspace .PVC .ClaimName == "" {
@@ -44,23 +55,48 @@ func newDownCmd(opts *Options) *cobra.Command {
4455 return nil
4556 }
4657
58+ ui .section ("Delete" )
59+ ui .stepRun ("pod" , podName (sn ))
4760 if err := k .Delete (ctx , ns , "pod" , podName (sn ), true ); err != nil && ! apierrors .IsNotFound (err ) {
4861 return fmt .Errorf ("delete session pod: %w" , err )
4962 }
63+ ui .stepDone ("pod" , "deleted" )
5064 if deletePVC && cfg .Spec .Workspace .PVC .ClaimName == "" {
65+ ui .stepRun ("pvc" , pvcName (cfg , sn ))
5166 if err := k .Delete (ctx , ns , "pvc" , pvcName (cfg , sn ), true ); err != nil && ! apierrors .IsNotFound (err ) {
5267 return fmt .Errorf ("delete workspace pvc: %w" , err )
5368 }
69+ ui .stepDone ("pvc" , "deleted" )
70+ } else if cfg .Spec .Workspace .PVC .ClaimName == "" {
71+ ui .stepDone ("pvc" , "retained" )
72+ } else {
73+ ui .stepDone ("pvc" , "external claim" )
5474 }
5575 alias := sshHostAlias (sn )
76+ ui .section ("Cleanup" )
5677 _ = stopManagedSSHForward (alias )
57- _ = removeSSHConfigEntry (alias )
78+ ui .stepDone ("ssh forward" , "stopped" )
79+ if err := removeSSHConfigEntry (alias ); err != nil {
80+ ui .warnf ("failed to remove SSH config entry for %s: %v" , alias , err )
81+ } else {
82+ ui .stepDone ("ssh config" , "cleaned" )
83+ }
5884 if active , err := session .LoadActiveSession (); err == nil && active == sn {
5985 _ = session .ClearActiveSession ()
86+ ui .stepDone ("active session" , "cleared" )
6087 }
61- fmt .Fprintf (cmd .OutOrStdout (), "Session stopped: %s\n " , sn )
88+ ui .printWarnings ()
89+ ui .section ("Ready" )
90+ fmt .Fprintf (cmd .OutOrStdout (), "session: %s\n " , sn )
91+ fmt .Fprintf (cmd .OutOrStdout (), "namespace: %s\n " , ns )
92+ fmt .Fprintln (cmd .OutOrStdout (), "status: stopped" )
6293 if ! deletePVC && cfg .Spec .Workspace .PVC .ClaimName == "" {
63- fmt .Fprintf (cmd .OutOrStdout (), "Workspace PVC retained: %s (use --delete-pvc to remove)\n " , pvcName (cfg , sn ))
94+ fmt .Fprintf (cmd .OutOrStdout (), "workspace: retained (%s)\n " , pvcName (cfg , sn ))
95+ fmt .Fprintln (cmd .OutOrStdout (), "note: use --delete-pvc to remove workspace storage" )
96+ } else if deletePVC && cfg .Spec .Workspace .PVC .ClaimName == "" {
97+ fmt .Fprintln (cmd .OutOrStdout (), "workspace: deleted" )
98+ } else {
99+ fmt .Fprintf (cmd .OutOrStdout (), "workspace: external claim (%s)\n " , cfg .Spec .Workspace .PVC .ClaimName )
64100 }
65101 return nil
66102 },
0 commit comments