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

Commit c823160

Browse files
author
Faris Huskovic
committed
finishing touches
1 parent 6e745bf commit c823160

File tree

3 files changed

+160
-80
lines changed

3 files changed

+160
-80
lines changed

internal/cmd/ceapi.go

+43-28
Original file line numberDiff line numberDiff line change
@@ -84,34 +84,12 @@ func findEnv(ctx context.Context, client *coder.Client, envName, userEmail strin
8484
}
8585

8686
func findImg(ctx context.Context, client *coder.Client, email, imgName string) (*coder.Image, error) {
87-
switch {
88-
case client == nil:
89-
return nil, xerrors.New("nil client")
90-
case email == "":
91-
return nil, xerrors.New("user email unset")
92-
case imgName == "":
93-
return nil, xerrors.New("img name unset")
94-
}
95-
96-
// Get all imported images for each org the user belongs to.
97-
imgs, err := getImportedImgs(ctx, client, email)
87+
userImgs, err := lookupUserImgs(ctx, client, email, imgName)
9888
if err != nil {
9989
return nil, err
10090
}
10191

102-
var matchingImgs []*coder.Image
103-
104-
// The user may provide an image thats not an exact match
105-
// to one of their imported images but they may be close.
106-
// We can assist the user by collecting images that contain
107-
// the user provided image flag value as a substring.
108-
for _, img := range imgs {
109-
if strings.Contains(img.Repository, imgName) {
110-
matchingImgs = append(matchingImgs, img)
111-
}
112-
}
113-
114-
numImgs := len(matchingImgs)
92+
numImgs := len(userImgs)
11593

11694
if numImgs == 0 {
11795
return nil, xerrors.New("image not found - did you forget to import this image?")
@@ -120,21 +98,21 @@ func findImg(ctx context.Context, client *coder.Client, email, imgName string) (
12098
if numImgs > 1 {
12199
var lines []string
122100

123-
for _, img := range matchingImgs {
101+
for _, img := range userImgs {
124102
lines = append(lines, img.Repository)
125103
}
126104

127105
clog.LogInfo(
128106
fmt.Sprintf("Found %d possible matches for %q.", numImgs, imgName),
129-
clog.Tipf("Did you mean? %s", strings.Join(lines, "\n")),
107+
clog.Tipf("Did you mean?\n\t%s", strings.Join(lines, "\n\t")),
130108
)
131109

132110
return nil, xerrors.New("please refine your search")
133111
}
134-
return matchingImgs[0], nil
112+
return userImgs[0], nil
135113
}
136114

137-
func getImportedImgs(ctx context.Context, client *coder.Client, userEmail string) ([]*coder.Image, error) {
115+
func getImgs(ctx context.Context, client *coder.Client, userEmail string) ([]*coder.Image, error) {
138116
u, err := client.UserByEmail(ctx, userEmail)
139117
if err != nil {
140118
return nil, err
@@ -158,3 +136,40 @@ func getImportedImgs(ctx context.Context, client *coder.Client, userEmail string
158136
}
159137
return importedImgs, nil
160138
}
139+
140+
// returns all images that contain imgName as a substring and have been imported by the user.
141+
func lookupUserImgs(ctx context.Context, client *coder.Client, email, imgName string) ([]*coder.Image, error) {
142+
switch {
143+
case client == nil:
144+
return nil, xerrors.New("nil client")
145+
case email == "":
146+
return nil, xerrors.New("user email unset")
147+
case imgName == "":
148+
return nil, xerrors.New("image name unset")
149+
}
150+
151+
// Get all imported images for each org the user belongs to.
152+
imgs, err := getImgs(ctx, client, email)
153+
if err != nil {
154+
return nil, err
155+
}
156+
157+
var userImgs []*coder.Image
158+
159+
// The user may provide an image thats not an exact match
160+
// to one of their imported images but they may be close.
161+
// We can assist the user by collecting images that contain
162+
// the user provided image flag value as a substring.
163+
for _, img := range imgs {
164+
if strings.Contains(img.Repository, imgName) {
165+
userImgs = append(userImgs, img)
166+
}
167+
// If it's an exact match we can overwrite the slice and exit the loop
168+
// since we won't need the fuzzy matched images anymore.
169+
if img.Repository == imgName {
170+
userImgs = []*coder.Image{img}
171+
break
172+
}
173+
}
174+
return userImgs, nil
175+
}

internal/cmd/envs.go

+114-51
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,6 @@ func editEnvCommand(user *string) *cobra.Command {
257257
258258
coder envs edit back-end-env --disk 20`,
259259
RunE: func(cmd *cobra.Command, args []string) error {
260-
// We're explicitly ignoring these errors because if any of these
261-
// fail we are left with the zero value for the corresponding numeric type.
262-
cpuCores, _ = cmd.Flags().GetFloat32("cpu")
263-
memGB, _ = cmd.Flags().GetFloat32("memory")
264-
diskGB, _ = cmd.Flags().GetInt("disk")
265-
gpus, _ = cmd.Flags().GetInt("gpus")
266-
267260
client, err := newClient()
268261
if err != nil {
269262
return err
@@ -276,52 +269,21 @@ coder envs edit back-end-env --disk 20`,
276269
return err
277270
}
278271

279-
var updateReq coder.UpdateEnvironmentReq
280-
281-
// If any of the flags have defaulted to zero-values, it implies the user does not wish to change that value.
282-
// With that said, we can enforce this by reassigning the request field to the corresponding existing environment value.
283-
if cpuCores == 0 {
284-
updateReq.CPUCores = &env.CPUCores
285-
} else {
286-
updateReq.CPUCores = &cpuCores
287-
}
288-
289-
if memGB == 0 {
290-
updateReq.MemoryGB = &env.MemoryGB
291-
} else {
292-
updateReq.MemoryGB = &memGB
293-
}
294-
295-
if diskGB == 0 {
296-
updateReq.DiskGB = &env.DiskGB
297-
} else {
298-
updateReq.DiskGB = &diskGB
299-
}
300-
301-
if gpus == 0 {
302-
updateReq.GPUs = &env.GPUs
303-
} else {
304-
updateReq.GPUs = &gpus
305-
}
306-
307-
if img != "" {
308-
importedImg, err := findImg(cmd.Context(), client, *user, img)
309-
if err != nil {
310-
return err
311-
}
312-
updateReq.ImageID = &importedImg.ID
313-
} else {
314-
updateReq.ImageID = &env.ImageID
315-
}
316-
317-
if tag == "" {
318-
updateReq.ImageTag = &env.ImageTag
319-
} else {
320-
updateReq.ImageTag = &tag
272+
req, err := buildUpdateReq(updateConf{
273+
command: cmd,
274+
client: client,
275+
environment: env,
276+
user: user,
277+
image: img,
278+
imageTag: tag,
279+
},
280+
)
281+
if err != nil {
282+
return err
321283
}
322284

323-
if err := client.EditEnvironment(cmd.Context(), env.ID, updateReq); err != nil {
324-
return xerrors.Errorf("failed to apply changes to environment: '%s'", envName)
285+
if err := client.EditEnvironment(cmd.Context(), env.ID, *req); err != nil {
286+
return xerrors.Errorf("failed to apply changes to environment %q: %w", envName, err)
325287
}
326288

327289
if follow {
@@ -406,3 +368,104 @@ func rmEnvsCommand(user *string) *cobra.Command {
406368
cmd.Flags().BoolVarP(&force, "force", "f", false, "force remove the specified environments without prompting first")
407369
return cmd
408370
}
371+
372+
type updateConf struct {
373+
command *cobra.Command
374+
client *coder.Client
375+
environment *coder.Environment
376+
user *string
377+
image string
378+
imageTag string
379+
}
380+
381+
func buildUpdateReq(conf updateConf) (*coder.UpdateEnvironmentReq, error) {
382+
var (
383+
updateReq coder.UpdateEnvironmentReq
384+
defaultCPUCores float32
385+
defaultMemGB float32
386+
defaultDiskGB int
387+
)
388+
389+
// If this is not empty it means the user is requesting to change the environment image.
390+
if conf.image != "" {
391+
importedImg, err := findImg(conf.command.Context(),
392+
conf.client,
393+
*conf.user,
394+
conf.image,
395+
)
396+
if err != nil {
397+
return nil, err
398+
}
399+
400+
// If the user passes an image arg of the image that
401+
// the environment is already using, it was most likely a mistake.
402+
if conf.image != importedImg.Repository {
403+
return nil, xerrors.Errorf("environment is already using image %q", conf.image)
404+
}
405+
406+
// Since the environment image is being changed,
407+
// the resource amount defaults should be changed to
408+
// reflect that of the default resource amounts of the new image.
409+
defaultCPUCores = importedImg.DefaultCPUCores
410+
defaultMemGB = importedImg.DefaultMemoryGB
411+
defaultDiskGB = importedImg.DefaultDiskGB
412+
updateReq.ImageID = &importedImg.ID
413+
} else {
414+
// if the environment image is not being changed, the default
415+
// resource amounts should reflect the default resource amounts
416+
// of the image the environment is already using.
417+
defaultCPUCores = conf.environment.CPUCores
418+
defaultMemGB = conf.environment.MemoryGB
419+
defaultDiskGB = conf.environment.DiskGB
420+
updateReq.ImageID = &conf.environment.ImageID
421+
}
422+
423+
// The following logic checks to see if the user specified
424+
// any resource amounts for the environment that need to be changed.
425+
// If they did not, then we will get the zero value back
426+
// and should set the resource amount to the default.
427+
428+
cpuCores, _ := conf.command.Flags().GetFloat32("cpu")
429+
if cpuCores == 0 {
430+
updateReq.CPUCores = &defaultCPUCores
431+
} else {
432+
updateReq.CPUCores = &cpuCores
433+
}
434+
435+
memGB, _ := conf.command.Flags().GetFloat32("memory")
436+
if memGB == 0 {
437+
updateReq.MemoryGB = &defaultMemGB
438+
} else {
439+
updateReq.MemoryGB = &memGB
440+
}
441+
442+
diskGB, _ := conf.command.Flags().GetInt("disk")
443+
if diskGB == 0 {
444+
updateReq.DiskGB = &defaultDiskGB
445+
} else {
446+
updateReq.DiskGB = &diskGB
447+
}
448+
449+
// Environment disks can not be shrink so we have to overwrite this
450+
// if the user accidentally requests it or if the default diskGB value for a
451+
// newly requested image is smaller than the current amount the environment is using.
452+
if *updateReq.DiskGB < conf.environment.DiskGB {
453+
updateReq.DiskGB = &conf.environment.DiskGB
454+
}
455+
456+
gpus, _ := conf.command.Flags().GetInt("gpus")
457+
if gpus != 0 {
458+
updateReq.GPUs = &gpus
459+
}
460+
461+
if conf.imageTag == "" {
462+
// We're forced to make an alloc here because untyped string consts are not addressable.
463+
// i.e. updateReq.ImageTag = &defaultImgTag results in :
464+
// invalid operation: cannot take address of defaultImgTag (untyped string constant "latest")
465+
imgTag := defaultImgTag
466+
updateReq.ImageTag = &imgTag
467+
} else {
468+
updateReq.ImageTag = &conf.imageTag
469+
}
470+
return &updateReq, nil
471+
}

swap.sh

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
#!/bin/bash
2-
rm $(which coder) && go install ./cmd/coder/*.go && echo "swapped binary"
2+
rm $(which coder)
3+
4+
cd ./cmd/coder/ && go install . && cd ../../ && echo "swapped binary"

0 commit comments

Comments
 (0)