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

Commit9d1ed0d

Browse files
author
Faris Huskovic
committed
Change coder create | edit envs image flag to take image name and use defaults from image
1 parent6f8b9b8 commit9d1ed0d

File tree

5 files changed

+338
-81
lines changed

5 files changed

+338
-81
lines changed

‎ci/integration/envs_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
)
1010

1111
// From Coder organization images
12-
constubuntuImgID="5f443b16-30652892427b955601330fa5"
12+
//const ubuntuImgID = "5f443b16-30652892427b955601330fa5"
1313

1414
funcTestEnvsCLI(t*testing.T) {
1515
t.Parallel()
@@ -37,6 +37,18 @@ func TestEnvsCLI(t *testing.T) {
3737
tcli.StderrEmpty(),
3838
)
3939

40+
// Image unset.
41+
c.Run(ctx,"coder envs create test-env").Assert(t,
42+
tcli.StderrMatches(regexp.QuoteMeta("fatal: required flag(s)\"image\" not set")),
43+
tcli.Error(),
44+
)
45+
46+
// Image not imported.
47+
c.Run(ctx,"coder envs create test-env --image doesntmatter").Assert(t,
48+
tcli.StderrMatches(regexp.QuoteMeta("fatal: image not found - did you forget to import this image?")),
49+
tcli.Error(),
50+
)
51+
4052
// TODO(Faris) : uncomment this when we can safely purge the environments
4153
// the integrations tests would create in the sidecar
4254
// Successfully create environment.
@@ -46,24 +58,12 @@ func TestEnvsCLI(t *testing.T) {
4658
// tcli.StderrMatches(regexp.QuoteMeta("Successfully created environment \"test-ubuntu\"")),
4759
// )
4860

49-
// Invalid environment name should fail.
50-
c.Run(ctx,"coder envs create --image "+ubuntuImgID+" this-IS-an-invalid-EnvironmentName").Assert(t,
51-
tcli.Error(),
52-
tcli.StderrMatches(regexp.QuoteMeta("environment name must conform to regex ^[a-z0-9]([a-z0-9-]+)?")),
53-
)
54-
5561
// TODO(Faris) : uncomment this when we can safely purge the environments
5662
// the integrations tests would create in the sidecar
5763
// Successfully provision environment with fractional resource amounts
5864
// c.Run(ctx, fmt.Sprintf(`coder envs create -i %s -c 1.2 -m 1.4 non-whole-resource-amounts`, ubuntuImgID)).Assert(t,
5965
// tcli.Success(),
6066
// tcli.StderrMatches(regexp.QuoteMeta("Successfully created environment \"non-whole-resource-amounts\"")),
6167
// )
62-
63-
// Image does not exist should fail.
64-
c.Run(ctx,"coder envs create --image does-not-exist env-will-not-be-created").Assert(t,
65-
tcli.Error(),
66-
tcli.StderrMatches(regexp.QuoteMeta("does not exist")),
67-
)
6868
})
6969
}

‎coder-sdk/image.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type Image struct {
1313
Descriptionstring`json:"description"`
1414
URLstring`json:"url"`// User-supplied URL for image.
1515
DefaultCPUCoresfloat32`json:"default_cpu_cores"`
16-
DefaultMemoryGBint`json:"default_memory_gb"`
16+
DefaultMemoryGBfloat32`json:"default_memory_gb"`
1717
DefaultDiskGBint`json:"default_disk_gb"`
1818
Deprecatedbool`json:"deprecated"`
1919
}
@@ -47,3 +47,12 @@ func (c Client) ImportImage(ctx context.Context, orgID string, req ImportImageRe
4747
}
4848
return&img,nil
4949
}
50+
51+
// OrganizationImages returns all of the images imported for orgID.
52+
func (cClient)OrganizationImages(ctx context.Context,orgIDstring) ([]Image,error) {
53+
varimgs []Image
54+
iferr:=c.requestBody(ctx,http.MethodGet,"/api/orgs/"+orgID+"/images",nil,&imgs);err!=nil {
55+
returnnil,err
56+
}
57+
returnimgs,nil
58+
}

‎internal/clog/error.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ func LogSuccess(header string, lines ...string) {
6868
}.String())
6969
}
7070

71+
// LogWarn prints the given warn message to stderr.
72+
funcLogWarn(headerstring,lines...string) {
73+
fmt.Fprint(os.Stderr,CLIMessage{
74+
Level:"warning",
75+
Color:color.FgYellow,
76+
Header:header,
77+
Lines:lines,
78+
}.String())
79+
}
80+
7181
// Warn creates an error with the level "warning".
7282
funcWarn(headerstring,lines...string)CLIError {
7383
returnCLIError{

‎internal/cmd/ceapi.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cmd
33
import (
44
"context"
55
"fmt"
6+
"strings"
67

78
"cdr.dev/coder-cli/coder-sdk"
89
"cdr.dev/coder-cli/internal/clog"
@@ -81,3 +82,116 @@ func findEnv(ctx context.Context, client *coder.Client, envName, userEmail strin
8182
clog.Tipf("run\"coder envs ls\" to view your environments"),
8283
)
8384
}
85+
86+
typefindImgConfstruct {
87+
client*coder.Client
88+
emailstring
89+
imgNamestring
90+
orgNamestring
91+
}
92+
93+
funcfindImg(ctx context.Context,conffindImgConf) (*coder.Image,error) {
94+
switch {
95+
caseconf.email=="":
96+
returnnil,xerrors.New("user email unset")
97+
caseconf.imgName=="":
98+
returnnil,xerrors.New("image name unset")
99+
}
100+
101+
imgs,err:=getImgs(ctx,
102+
getImgsConf{
103+
client:conf.client,
104+
email:conf.email,
105+
orgName:conf.orgName,
106+
},
107+
)
108+
iferr!=nil {
109+
returnnil,err
110+
}
111+
112+
varpossibleMatches []coder.Image
113+
114+
// The user may provide an image thats not an exact match
115+
// to one of their imported images but they may be close.
116+
// We can assist the user by collecting images that contain
117+
// the user provided image flag value as a substring.
118+
for_,img:=rangeimgs {
119+
// If it's an exact match we can just return and exit.
120+
ifimg.Repository==conf.imgName {
121+
return&img,nil
122+
}
123+
ifstrings.Contains(img.Repository,conf.imgName) {
124+
possibleMatches=append(possibleMatches,img)
125+
}
126+
}
127+
128+
iflen(possibleMatches)==0 {
129+
returnnil,xerrors.New("image not found - did you forget to import this image?")
130+
}
131+
132+
lines:= []string{clog.Tipf("Did you mean?")}
133+
134+
for_,img:=rangepossibleMatches {
135+
lines=append(lines,img.Repository)
136+
}
137+
returnnil,clog.Fatal(
138+
fmt.Sprintf("Found %d possible matches for %q.",len(possibleMatches),conf.imgName),
139+
lines...,
140+
)
141+
}
142+
143+
typegetImgsConfstruct {
144+
client*coder.Client
145+
emailstring
146+
orgNamestring
147+
}
148+
149+
funcgetImgs(ctx context.Context,confgetImgsConf) ([]coder.Image,error) {
150+
u,err:=conf.client.UserByEmail(ctx,conf.email)
151+
iferr!=nil {
152+
returnnil,err
153+
}
154+
155+
orgs,err:=conf.client.Organizations(ctx)
156+
iferr!=nil {
157+
returnnil,err
158+
}
159+
160+
orgs=lookupUserOrgs(u,orgs)
161+
162+
for_,org:=rangeorgs {
163+
imgs,err:=conf.client.OrganizationImages(ctx,org.ID)
164+
iferr!=nil {
165+
returnnil,err
166+
}
167+
// If orgName is set we know the user is a multi-org member
168+
// so we should only return the imported images that beong to the org they specified.
169+
ifconf.orgName!=""&&conf.orgName==org.Name {
170+
returnimgs,nil
171+
}
172+
173+
ifconf.orgName=="" {
174+
// if orgName is unset we know the user is only part of one org.
175+
returnimgs,nil
176+
}
177+
}
178+
returnnil,xerrors.Errorf("org name %q not found",conf.orgName)
179+
}
180+
181+
funcisMultiOrgMember(ctx context.Context,emailstring) (bool,error) {
182+
client,err:=newClient()
183+
iferr!=nil {
184+
returnfalse,err
185+
}
186+
187+
u,err:=client.UserByEmail(ctx,email)
188+
iferr!=nil {
189+
returnfalse,xerrors.New("email not found")
190+
}
191+
192+
orgs,err:=client.Organizations(ctx)
193+
iferr!=nil {
194+
returnfalse,err
195+
}
196+
returnlen(lookupUserOrgs(u,orgs))>1,nil
197+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp