Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Aug 30, 2024. It is now read-only.
/coder-v1-cliPublic archive

Commitb86412b

Browse files
committed
implement basic env stat streaming stress test
1 parent2d52bb3 commitb86412b

File tree

12 files changed

+261
-14
lines changed

12 files changed

+261
-14
lines changed

‎cmd/stress/main.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package main
2+
3+
import (
4+
"cdr.dev/coder-cli/coder-sdk"
5+
"cdr.dev/coder-cli/internal/cmd"
6+
"context"
7+
"fmt"
8+
"golang.org/x/sync/errgroup"
9+
"log"
10+
"time"
11+
)
12+
13+
const (
14+
level=1
15+
statSeconds=30
16+
orgID="default"
17+
namePrefix="stress"
18+
imageID="5f282a6a-2b0fd967178a95ac8078ce31"// master.cdr.dev ubuntu
19+
imageTag="latest"
20+
cpuCores=1
21+
memoryGB=1
22+
diskGB=10
23+
)
24+
25+
funcmain() {
26+
ctx:=context.Background()
27+
g,ctx:=errgroup.WithContext(ctx)
28+
c:=cmd.RequireAuth()
29+
uid:=time.Now().Unix()
30+
31+
fori:=0;i<level;i++ {
32+
i:=i//https://golang.org/doc/faq#closures_and_goroutines
33+
g.Go(func()error {
34+
er:= coder.CreateEnvironmentRequest{
35+
Name:fmt.Sprintf("%s-%d-%d",namePrefix,uid,i),
36+
ImageID:imageID,
37+
ImageTag:imageTag,
38+
CPUCores:cpuCores,
39+
MemoryGB:memoryGB,
40+
DiskGB:diskGB,
41+
}
42+
43+
log.Printf("%s: Creating environment\n",er.Name)
44+
env,err:=c.CreateEnvironment(ctx,orgID,er)
45+
iferr!=nil {
46+
returnfmt.Errorf("create environment: %w",err)
47+
}
48+
49+
log.Printf("%s: Waiting for environment to be ready\n",er.Name)
50+
err=c.WaitForEnvironmentReady(ctx,env.ID)
51+
iferr!=nil {
52+
returnfmt.Errorf("wait for environment ready: %w",err)
53+
}
54+
55+
log.Printf("%s: Watching environment stats for %d seconds\n",er.Name,statSeconds)
56+
err=c.WatchEnvironmentStats(ctx,env.ID,time.Second*statSeconds)
57+
iferr!=nil {
58+
returnfmt.Errorf("watch environment stats: %w",err)
59+
}
60+
61+
log.Printf("%s: Deleting environment\n",er.Name)
62+
err=c.DeleteEnvironment(ctx,env.ID)
63+
iferr!=nil {
64+
returnfmt.Errorf("delete environment: %w",err)
65+
}
66+
returnnil
67+
})
68+
}
69+
err:=g.Wait()
70+
iferr!=nil {
71+
log.Fatal(err)
72+
}
73+
}

‎coder-sdk/env.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package coder
22

33
import (
44
"context"
5+
"fmt"
56
"net/http"
7+
"nhooyr.io/websocket/wsjson"
68
"time"
79

810
"cdr.dev/coder-cli/internal/x/xjson"
@@ -75,3 +77,122 @@ func (c Client) DialWsep(ctx context.Context, env *Environment) (*websocket.Conn
7577
}
7678
returnconn,nil
7779
}
80+
81+
typeCreateEnvironmentRequeststruct {
82+
Namestring`json:"name"`
83+
ImageIDstring`json:"image_id"`
84+
ImageTagstring`json:"image_tag"`
85+
CPUCoresfloat32`json:"cpu_cores"`
86+
MemoryGBint`json:"memory_gb"`
87+
DiskGBint`json:"disk_gb"`
88+
GPUsint`json:"gpus"`// can be set to 0
89+
Services []string`json:"services"`
90+
}
91+
92+
func (cClient)CreateEnvironment(ctx context.Context,orgIDstring,reqCreateEnvironmentRequest) (Environment,error) {
93+
varenvEnvironment
94+
err:=c.requestBody(
95+
ctx,
96+
http.MethodPost,"/api/orgs/"+orgID+"/environments",
97+
req,
98+
&env,
99+
)
100+
returnenv,err
101+
}
102+
103+
typeenvUpdatestruct {
104+
Typestring`json:"type"`
105+
}
106+
107+
func (cClient)WaitForEnvironmentReady(ctx context.Context,envIDstring)error {
108+
u:=c.copyURL()
109+
ifc.BaseURL.Scheme=="https" {
110+
u.Scheme="wss"
111+
}else {
112+
u.Scheme="ws"
113+
}
114+
u.Path="/api/environments/"+envID+"/watch-update"
115+
116+
conn,resp,err:=websocket.Dial(ctx,u.String(),
117+
&websocket.DialOptions{
118+
HTTPHeader:map[string][]string{
119+
"Cookie": {"session_token="+c.Token},
120+
},
121+
},
122+
)
123+
iferr!=nil {
124+
ifresp!=nil {
125+
returnbodyError(resp)
126+
}
127+
returnerr
128+
}
129+
130+
for {
131+
m:=envUpdate{}
132+
err=wsjson.Read(ctx,conn,&m)
133+
iferr!=nil {
134+
returnfmt.Errorf("read ws json msg: %w",err)
135+
}
136+
ifm.Type=="done" {
137+
break
138+
}
139+
}
140+
141+
returnnil
142+
}
143+
144+
typestatsstruct {
145+
ContainerStatusstring`json:"container_status"`
146+
StatErrorstring`json:"stat_error"`
147+
Timestring`json:"time"`
148+
}
149+
150+
func (cClient)WatchEnvironmentStats(ctx context.Context,envIDstring,duration time.Duration)error {
151+
u:=c.copyURL()
152+
ifc.BaseURL.Scheme=="https" {
153+
u.Scheme="wss"
154+
}else {
155+
u.Scheme="ws"
156+
}
157+
u.Path="/api/environments/"+envID+"/watch-stats"
158+
159+
conn,resp,err:=websocket.Dial(ctx,u.String(),
160+
&websocket.DialOptions{
161+
HTTPHeader:map[string][]string{
162+
"Cookie": {"session_token="+c.Token},
163+
},
164+
},
165+
)
166+
iferr!=nil {
167+
ifresp!=nil {
168+
returnbodyError(resp)
169+
}
170+
returnerr
171+
}
172+
173+
statsCtx,statsCancel:=context.WithTimeout(ctx,duration)
174+
deferstatsCancel()
175+
176+
for {
177+
select {
178+
case<-statsCtx.Done():
179+
returnnil
180+
default:
181+
m:=stats{}
182+
err=wsjson.Read(ctx,conn,&m)
183+
iferr!=nil {
184+
returnfmt.Errorf("read ws json msg: %w",err)
185+
}
186+
}
187+
}
188+
}
189+
190+
func (cClient)DeleteEnvironment(ctx context.Context,envIDstring)error {
191+
err:=c.requestBody(
192+
ctx,
193+
http.MethodDelete,"/api/environments/"+envID,
194+
nil,
195+
nil,
196+
)
197+
returnerr
198+
}

‎coder-sdk/image.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package coder
2+
3+
import (
4+
"context"
5+
"net/http"
6+
)
7+
8+
typeImagestruct {
9+
IDstring`json:"id"`
10+
OrganizationIDstring`json:"organization_id"`
11+
Repositorystring`json:"repository"`
12+
Descriptionstring`json:"description"`
13+
URLstring`json:"url"`// user-supplied URL for image
14+
DefaultCPUCoresfloat32`json:"default_cpu_cores"`
15+
DefaultMemoryGBint`json:"default_memory_gb"`
16+
DefaultDiskGBint`json:"default_disk_gb"`
17+
Deprecatedbool`json:"deprecated"`
18+
}
19+
20+
typeNewRegistryRequeststruct {
21+
FriendlyNamestring`json:"friendly_name"`
22+
Registrystring`json:"registry"`
23+
Usernamestring`json:"username"`
24+
Passwordstring`json:"password"`
25+
}
26+
27+
typeImportImageRequeststruct {
28+
// RegistryID is used to import images to existing registries.
29+
RegistryID*string`json:"registry_id"`
30+
// NewRegistry is used when adding a new registry.
31+
NewRegistry*NewRegistryRequest`json:"new_registry"`
32+
// Repository refers to the image. For example: "codercom/ubuntu".
33+
Repositorystring`json:"repository"`
34+
Tagstring`json:"tag"`
35+
DefaultCPUCoresfloat32`json:"default_cpu_cores"`
36+
DefaultMemoryGBint`json:"default_memory_gb"`
37+
DefaultDiskGBint`json:"default_disk_gb"`
38+
Descriptionstring`json:"description"`
39+
URLstring`json:"url"`
40+
}
41+
42+
func (cClient)ImportImage(ctx context.Context,orgIDstring,reqImportImageRequest) (Image,error) {
43+
varimgImage
44+
err:=c.requestBody(
45+
ctx,
46+
http.MethodPost,"/api/orgs/"+orgID+"/images",
47+
req,
48+
&img,
49+
)
50+
returnimg,err
51+
}

‎coder-sdk/users.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,5 @@ func (c Client) UserByEmail(ctx context.Context, email string) (*User, error) {
7373
}
7474
returnnil,ErrNotFound
7575
}
76+
77+

‎internal/cmd/auth.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
"go.coder.com/flog"
1111
)
1212

13-
//requireAuth exits the process with a nonzero exit code if the user is not authenticated to make requests
14-
funcrequireAuth()*coder.Client {
13+
//RequireAuth exits the process with a nonzero exit code if the user is not authenticated to make requests
14+
funcRequireAuth()*coder.Client {
1515
client,err:=newClient()
1616
iferr!=nil {
1717
flog.Fatal("%v",err)

‎internal/cmd/configssh.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func configSSH(configpath *string, remove *bool) func(cmd *cobra.Command, _ []st
8585
returnnil
8686
}
8787

88-
client:=requireAuth()
88+
client:=RequireAuth()
8989

9090
sshAvailable:=isSSHAvailable(ctx)
9191
if!sshAvailable {

‎internal/cmd/envs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func makeEnvsCommand() *cobra.Command {
2727
Short:"list all environments owned by the active user",
2828
Long:"List all Coder environments owned by the active user.",
2929
RunE:func(cmd*cobra.Command,args []string)error {
30-
entClient:=requireAuth()
30+
entClient:=RequireAuth()
3131
envs,err:=getEnvs(cmd.Context(),entClient,user)
3232
iferr!=nil {
3333
returnerr

‎internal/cmd/secrets.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ coder secrets create aws-credentials --from-file ./credentials.json`,
7979
},
8080
RunE:func(cmd*cobra.Command,args []string)error {
8181
var (
82-
client=requireAuth()
82+
client=RequireAuth()
8383
name=args[0]
8484
valuestring
8585
errerror
@@ -135,7 +135,7 @@ coder secrets create aws-credentials --from-file ./credentials.json`,
135135

136136
funclistSecrets(userEmail*string)func(cmd*cobra.Command,_ []string)error {
137137
returnfunc(cmd*cobra.Command,_ []string)error {
138-
client:=requireAuth()
138+
client:=RequireAuth()
139139
user,err:=client.UserByEmail(cmd.Context(),*userEmail)
140140
iferr!=nil {
141141
returnxerrors.Errorf("get user %q by email: %w",*userEmail,err)
@@ -166,7 +166,7 @@ func listSecrets(userEmail *string) func(cmd *cobra.Command, _ []string) error {
166166
funcmakeViewSecret(userEmail*string)func(cmd*cobra.Command,args []string)error {
167167
returnfunc(cmd*cobra.Command,args []string)error {
168168
var (
169-
client=requireAuth()
169+
client=RequireAuth()
170170
name=args[0]
171171
)
172172
user,err:=client.UserByEmail(cmd.Context(),*userEmail)
@@ -190,7 +190,7 @@ func makeViewSecret(userEmail *string) func(cmd *cobra.Command, args []string) e
190190
funcmakeRemoveSecrets(userEmail*string)func(c*cobra.Command,args []string)error {
191191
returnfunc(cmd*cobra.Command,args []string)error {
192192
var (
193-
client=requireAuth()
193+
client=RequireAuth()
194194
)
195195
user,err:=client.UserByEmail(cmd.Context(),*userEmail)
196196
iferr!=nil {

‎internal/cmd/shell.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func sendResizeEvents(ctx context.Context, termfd uintptr, process wsep.Process)
9797

9898
funcrunCommand(ctx context.Context,envNamestring,commandstring,args []string)error {
9999
var (
100-
entClient=requireAuth()
100+
entClient=RequireAuth()
101101
)
102102
env,err:=findEnv(ctx,entClient,envName,coder.Me)
103103
iferr!=nil {

‎internal/cmd/sync.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func makeRunSync(init *bool) func(cmd *cobra.Command, args []string) error {
5252
remote=args[1]
5353
)
5454

55-
entClient:=requireAuth()
55+
entClient:=RequireAuth()
5656

5757
info,err:=os.Stat(local)
5858
iferr!=nil {

‎internal/cmd/urls.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func makeCreateDevURL() *cobra.Command {
153153
ifurlname!=""&&!devURLNameValidRx.MatchString(urlname) {
154154
returnxerrors.New("update devurl: name must be < 64 chars in length, begin with a letter and only contain letters or digits.")
155155
}
156-
entClient:=requireAuth()
156+
entClient:=RequireAuth()
157157

158158
env,err:=findEnv(cmd.Context(),entClient,envName,coder.Me)
159159
iferr!=nil {
@@ -219,7 +219,7 @@ func removeDevURL(cmd *cobra.Command, args []string) error {
219219
returnxerrors.Errorf("validate port: %w",err)
220220
}
221221

222-
entClient:=requireAuth()
222+
entClient:=RequireAuth()
223223
env,err:=findEnv(cmd.Context(),entClient,envName,coder.Me)
224224
iferr!=nil {
225225
returnerr
@@ -246,7 +246,7 @@ func removeDevURL(cmd *cobra.Command, args []string) error {
246246

247247
// urlList returns the list of active devURLs from the cemanager.
248248
funcurlList(ctx context.Context,envNamestring) ([]DevURL,error) {
249-
entClient:=requireAuth()
249+
entClient:=RequireAuth()
250250
env,err:=findEnv(ctx,entClient,envName,coder.Me)
251251
iferr!=nil {
252252
returnnil,err

‎internal/cmd/users.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ coder users ls -o json | jq .[] | jq -r .email`,
3131

3232
funclistUsers(outputFmt*string)func(cmd*cobra.Command,args []string)error {
3333
returnfunc(cmd*cobra.Command,args []string)error {
34-
entClient:=requireAuth()
34+
entClient:=RequireAuth()
3535

3636
users,err:=entClient.Users(cmd.Context())
3737
iferr!=nil {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp