Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit a6c998c

Browse files
committed
Add coder envs rm command for removing environments
1 parent 924ebad commit a6c998c

File tree

3 files changed

+112
-11
lines changed

3 files changed

+112
-11
lines changed

docs/coder_envs.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ Perform operations on the Coder environments owned by the active user.
2323

2424
* [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation
2525
* [coder envs ls](coder_envs_ls.md) - list all environments owned by the active user
26+
* [coder envs rm](coder_envs_rm.md) - remove Coder environments by name
2627
* [coder envs stop](coder_envs_stop.md) - stop Coder environments by name
2728

docs/coder_envs_rm.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## coder envs rm
2+
3+
remove Coder environments by name
4+
5+
### Synopsis
6+
7+
remove Coder environments by name
8+
9+
```
10+
coder envs rm [...environment_names] [flags]
11+
```
12+
13+
### Options
14+
15+
```
16+
-f, --force force remove the specified environments without prompting first
17+
-h, --help help for rm
18+
```
19+
20+
### Options inherited from parent commands
21+
22+
```
23+
--user string Specify the user whose resources to target (default "me")
24+
-v, --verbose show verbose output
25+
```
26+
27+
### SEE ALSO
28+
29+
* [coder envs](coder_envs.md) - Interact with Coder environments

internal/cmd/envs.go

+82-11
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import (
99
"cdr.dev/coder-cli/coder-sdk"
1010
"cdr.dev/coder-cli/internal/clog"
1111
"cdr.dev/coder-cli/internal/x/xtabwriter"
12+
"github.com/manifoldco/promptui"
1213
"github.com/spf13/cobra"
1314
"golang.org/x/sync/errgroup"
15+
"golang.org/x/sync/semaphore"
1416
"golang.org/x/xerrors"
1517
)
1618

@@ -24,7 +26,6 @@ const (
2426
)
2527

2628
func envsCommand() *cobra.Command {
27-
var outputFmt string
2829
var user string
2930
cmd := &cobra.Command{
3031
Use: "envs",
@@ -33,7 +34,22 @@ func envsCommand() *cobra.Command {
3334
}
3435
cmd.PersistentFlags().StringVar(&user, "user", coder.Me, "Specify the user whose resources to target")
3536

36-
lsCmd := &cobra.Command{
37+
cmd.AddCommand(
38+
lsEnvsCommand(&user),
39+
stopEnvsCommand(&user),
40+
rmEnvsCommand(&user),
41+
watchBuildLogCommand(),
42+
rebuildEnvCommand(),
43+
createEnvCommand(),
44+
editEnvCommand(&user),
45+
)
46+
return cmd
47+
}
48+
49+
func lsEnvsCommand(user *string) *cobra.Command {
50+
var outputFmt string
51+
52+
cmd := &cobra.Command{
3753
Use: "ls",
3854
Short: "list all environments owned by the active user",
3955
Long: "List all Coder environments owned by the active user.",
@@ -42,7 +58,7 @@ func envsCommand() *cobra.Command {
4258
if err != nil {
4359
return err
4460
}
45-
envs, err := getEnvs(cmd.Context(), client, user)
61+
envs, err := getEnvs(cmd.Context(), client, *user)
4662
if err != nil {
4763
return err
4864
}
@@ -70,17 +86,13 @@ func envsCommand() *cobra.Command {
7086
return nil
7187
},
7288
}
73-
lsCmd.Flags().StringVarP(&outputFmt, "output", "o", "human", "human | json")
74-
cmd.AddCommand(lsCmd)
75-
cmd.AddCommand(editEnvCommand(&user))
76-
cmd.AddCommand(stopEnvCommand(&user))
77-
cmd.AddCommand(watchBuildLogCommand())
78-
cmd.AddCommand(rebuildEnvCommand())
79-
cmd.AddCommand(createEnvCommand())
89+
90+
cmd.Flags().StringVarP(&outputFmt, "output", "o", "human", "human | json")
91+
8092
return cmd
8193
}
8294

83-
func stopEnvCommand(user *string) *cobra.Command {
95+
func stopEnvsCommand(user *string) *cobra.Command {
8496
return &cobra.Command{
8597
Use: "stop [...environment_names]",
8698
Short: "stop Coder environments by name",
@@ -310,3 +322,62 @@ coder envs edit back-end-env --disk 20`,
310322
cmd.Flags().BoolVar(&follow, "follow", false, "follow buildlog after initiating rebuild")
311323
return cmd
312324
}
325+
326+
func rmEnvsCommand(user *string) *cobra.Command {
327+
var force bool
328+
cmd := &cobra.Command{
329+
Use: "rm [...environment_names]",
330+
Short: "remove Coder environments by name",
331+
Args: cobra.MinimumNArgs(1),
332+
RunE: func(cmd *cobra.Command, args []string) error {
333+
ctx := cmd.Context()
334+
client, err := newClient()
335+
if err != nil {
336+
return err
337+
}
338+
339+
// only show one confirmation dialogue at a time
340+
confirmLimiter := semaphore.NewWeighted(1)
341+
342+
var egroup errgroup.Group
343+
for _, envName := range args {
344+
envName := envName
345+
egroup.Go(func() error {
346+
env, err := findEnv(ctx, client, envName, *user)
347+
if err != nil {
348+
clog.Log(err)
349+
return err
350+
}
351+
if !force {
352+
confirm := promptui.Prompt{
353+
Label: fmt.Sprintf("Delete environment \"%s\"? (all data will be lost)", env.Name),
354+
IsConfirm: true,
355+
}
356+
if err := confirmLimiter.Acquire(ctx, 1); err != nil {
357+
return err
358+
}
359+
360+
if _, err = confirm.Run(); err != nil {
361+
confirmLimiter.Release(1)
362+
return xerrors.Errorf("confirm deletion of environment \"%s\"", env.Name)
363+
}
364+
confirmLimiter.Release(1)
365+
}
366+
if err = client.DeleteEnvironment(cmd.Context(), env.ID); err != nil {
367+
err = clog.Error(fmt.Sprintf(`failed to delete environment "%s"`, env.Name), clog.Cause(err.Error()))
368+
clog.Log(err)
369+
return err
370+
}
371+
return nil
372+
})
373+
}
374+
375+
if err = egroup.Wait(); err != nil {
376+
return xerrors.Errorf("some environment remove operations failed")
377+
}
378+
return nil
379+
},
380+
}
381+
cmd.Flags().BoolVarP(&force, "force", "f", false, "force remove the specified environments without prompting first")
382+
return cmd
383+
}

0 commit comments

Comments
 (0)