@@ -24,20 +24,22 @@ import (
24
24
"github.com/coder/coder/coderd/autobuild/schedule"
25
25
"github.com/coder/coder/coderd/database"
26
26
"github.com/coder/coder/codersdk"
27
+ "github.com/coder/coder/cryptorand"
27
28
)
28
29
29
30
var autostopPollInterval = 30 * time .Second
30
31
var autostopNotifyCountdown = []time.Duration {30 * time .Minute }
31
32
32
33
func ssh () * cobra.Command {
33
34
var (
34
- stdio bool
35
+ stdio bool
36
+ shuffle bool
35
37
)
36
38
cmd := & cobra.Command {
37
39
Annotations : workspaceCommand ,
38
40
Use : "ssh <workspace>" ,
39
41
Short : "SSH into a workspace" ,
40
- Args : cobra .MinimumNArgs ( 1 ) ,
42
+ Args : cobra .ArbitraryArgs ,
41
43
RunE : func (cmd * cobra.Command , args []string ) error {
42
44
client , err := createClient (cmd )
43
45
if err != nil {
@@ -48,10 +50,38 @@ func ssh() *cobra.Command {
48
50
return err
49
51
}
50
52
51
- workspaceParts := strings .Split (args [0 ], "." )
52
- workspace , err := client .WorkspaceByOwnerAndName (cmd .Context (), organization .ID , codersdk .Me , workspaceParts [0 ])
53
- if err != nil {
54
- return err
53
+ var workspace codersdk.Workspace
54
+ var workspaceParts []string
55
+ if shuffle {
56
+ err := cobra .ExactArgs (0 )(cmd , args )
57
+ if err != nil {
58
+ return err
59
+ }
60
+
61
+ workspaces , err := client .WorkspacesByOwner (cmd .Context (), organization .ID , codersdk .Me )
62
+ if err != nil {
63
+ return err
64
+ }
65
+ if len (workspaces ) == 0 {
66
+ return xerrors .New ("no workspaces to shuffle" )
67
+ }
68
+
69
+ idx , err := cryptorand .Intn (len (workspaces ))
70
+ if err != nil {
71
+ return err
72
+ }
73
+ workspace = workspaces [idx ]
74
+ } else {
75
+ err := cobra .MinimumNArgs (1 )(cmd , args )
76
+ if err != nil {
77
+ return err
78
+ }
79
+
80
+ workspaceParts = strings .Split (args [0 ], "." )
81
+ workspace , err = client .WorkspaceByOwnerAndName (cmd .Context (), organization .ID , codersdk .Me , workspaceParts [0 ])
82
+ if err != nil {
83
+ return err
84
+ }
55
85
}
56
86
57
87
if workspace .LatestBuild .Transition != database .WorkspaceTransitionStart {
@@ -96,9 +126,17 @@ func ssh() *cobra.Command {
96
126
}
97
127
if agent .ID == uuid .Nil {
98
128
if len (agents ) > 1 {
99
- return xerrors .New ("you must specify the name of an agent" )
129
+ if ! shuffle {
130
+ return xerrors .New ("you must specify the name of an agent" )
131
+ }
132
+ idx , err := cryptorand .Intn (len (agents ))
133
+ if err != nil {
134
+ return err
135
+ }
136
+ agent = agents [idx ]
137
+ } else {
138
+ agent = agents [0 ]
100
139
}
101
- agent = agents [0 ]
102
140
}
103
141
// OpenSSH passes stderr directly to the calling TTY.
104
142
// This is required in "stdio" mode so a connecting indicator can be displayed.
@@ -189,6 +227,8 @@ func ssh() *cobra.Command {
189
227
},
190
228
}
191
229
cliflag .BoolVarP (cmd .Flags (), & stdio , "stdio" , "" , "CODER_SSH_STDIO" , false , "Specifies whether to emit SSH output over stdin/stdout." )
230
+ cliflag .BoolVarP (cmd .Flags (), & shuffle , "shuffle" , "" , "CODER_SSH_SHUFFLE" , false , "Specifies whether to choose a random workspace" )
231
+ _ = cmd .Flags ().MarkHidden ("shuffle" )
192
232
193
233
return cmd
194
234
}
0 commit comments