From 2c14487e6fe4a5bd0cb9545d31e379bc0352599f Mon Sep 17 00:00:00 2001 From: fuskovic Date: Tue, 20 Oct 2020 22:18:07 -0500 Subject: [PATCH] Add envs create command --- ci/integration/envs_test.go | 69 +++++++++++++++++++++++++++++ ci/steps/gendocs.sh | 6 --- coder-sdk/env.go | 2 +- docs/coder.md | 1 + docs/coder_completion.md | 1 + docs/coder_config-ssh.md | 1 + docs/coder_envs.md | 1 + docs/coder_envs_ls.md | 1 + docs/coder_envs_stop.md | 1 + docs/coder_login.md | 1 + docs/coder_logout.md | 1 + docs/coder_secrets.md | 1 + docs/coder_secrets_create.md | 1 + docs/coder_secrets_ls.md | 1 + docs/coder_secrets_rm.md | 1 + docs/coder_secrets_view.md | 1 + docs/coder_sh.md | 1 + docs/coder_sync.md | 1 + docs/coder_urls.md | 1 + docs/coder_urls_create.md | 1 + docs/coder_urls_ls.md | 1 + docs/coder_urls_rm.md | 1 + docs/coder_users.md | 1 + docs/coder_users_ls.md | 1 + internal/cmd/cmd.go | 9 ++-- internal/cmd/envs.go | 84 +++++++++++++++++++++++++++++++++++- 26 files changed, 179 insertions(+), 12 deletions(-) create mode 100644 ci/integration/envs_test.go diff --git a/ci/integration/envs_test.go b/ci/integration/envs_test.go new file mode 100644 index 00000000..2f3c19c8 --- /dev/null +++ b/ci/integration/envs_test.go @@ -0,0 +1,69 @@ +package integration + +import ( + "context" + "regexp" + "testing" + + "cdr.dev/coder-cli/ci/tcli" +) + +// From Coder organization images +const ubuntuImgID = "5f443b16-30652892427b955601330fa5" + +func TestEnvsCLI(t *testing.T) { + t.Parallel() + + run(t, "coder-cli-env-tests", func(t *testing.T, ctx context.Context, c *tcli.ContainerRunner) { + headlessLogin(ctx, t, c) + + // Ensure binary is present. + c.Run(ctx, "which coder").Assert(t, + tcli.Success(), + tcli.StdoutMatches("/usr/sbin/coder"), + tcli.StderrEmpty(), + ) + + // Minimum args not received. + c.Run(ctx, "coder envs create").Assert(t, + tcli.StderrMatches(regexp.QuoteMeta("accepts 1 arg(s), received 0")), + tcli.Error(), + ) + + // Successfully output help. + c.Run(ctx, "coder envs create --help").Assert(t, + tcli.Success(), + tcli.StdoutMatches(regexp.QuoteMeta("Create a new environment under the active user.")), + tcli.StderrEmpty(), + ) + + // TODO(Faris) : uncomment this when we can safely purge the environments + // the integrations tests would create in the sidecar + // Successfully create environment. + // c.Run(ctx, "coder envs create --image "+ubuntuImgID+" test-ubuntu").Assert(t, + // tcli.Success(), + // // why does flog.Success write to stderr? + // tcli.StderrMatches(regexp.QuoteMeta("Successfully created environment \"test-ubuntu\"")), + // ) + + // Invalid environment name should fail. + c.Run(ctx, "coder envs create --image "+ubuntuImgID+" this-IS-an-invalid-EnvironmentName").Assert(t, + tcli.Error(), + tcli.StderrMatches(regexp.QuoteMeta("environment name must conform to regex ^[a-z0-9]([a-z0-9-]+)?")), + ) + + // TODO(Faris) : uncomment this when we can safely purge the environments + // the integrations tests would create in the sidecar + // Successfully provision environment with fractional resource amounts + // c.Run(ctx, fmt.Sprintf(`coder envs create -i %s -c 1.2 -m 1.4 non-whole-resource-amounts`, ubuntuImgID)).Assert(t, + // tcli.Success(), + // tcli.StderrMatches(regexp.QuoteMeta("Successfully created environment \"non-whole-resource-amounts\"")), + // ) + + // Image does not exist should fail. + c.Run(ctx, "coder envs create --image does-not-exist env-will-not-be-created").Assert(t, + tcli.Error(), + tcli.StderrMatches(regexp.QuoteMeta("does not exist")), + ) + }) +} diff --git a/ci/steps/gendocs.sh b/ci/steps/gendocs.sh index 9e31b626..cc397e4f 100755 --- a/ci/steps/gendocs.sh +++ b/ci/steps/gendocs.sh @@ -11,12 +11,6 @@ rm -rf ./docs mkdir ./docs go run ./cmd/coder gen-docs ./docs -# remove cobra footer from each file -for filename in ./docs/*.md; do - trimmed=$(head -n -1 "$filename") - echo "$trimmed" >$filename -done - if [[ ${CI-} && $(git ls-files --other --modified --exclude-standard) ]]; then echo "Documentation needs generation:" git -c color.ui=always status | grep --color=no '\e\[31m' diff --git a/coder-sdk/env.go b/coder-sdk/env.go index 6bc2f2ba..2eced5f1 100644 --- a/coder-sdk/env.go +++ b/coder-sdk/env.go @@ -78,7 +78,7 @@ type CreateEnvironmentRequest struct { ImageID string `json:"image_id"` ImageTag string `json:"image_tag"` CPUCores float32 `json:"cpu_cores"` - MemoryGB int `json:"memory_gb"` + MemoryGB float32 `json:"memory_gb"` DiskGB int `json:"disk_gb"` GPUs int `json:"gpus"` Services []string `json:"services"` diff --git a/docs/coder.md b/docs/coder.md index 844267d5..9542c51d 100644 --- a/docs/coder.md +++ b/docs/coder.md @@ -25,3 +25,4 @@ coder provides a CLI for working with an existing Coder Enterprise installation * [coder sync](coder_sync.md) - Establish a one way directory sync to a Coder environment * [coder urls](coder_urls.md) - Interact with environment DevURLs * [coder users](coder_users.md) - Interact with Coder user accounts + diff --git a/docs/coder_completion.md b/docs/coder_completion.md index 44f5519a..505fb8ca 100644 --- a/docs/coder_completion.md +++ b/docs/coder_completion.md @@ -67,3 +67,4 @@ MacOS: ### SEE ALSO * [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation + diff --git a/docs/coder_config-ssh.md b/docs/coder_config-ssh.md index b9f1e882..8e076fca 100644 --- a/docs/coder_config-ssh.md +++ b/docs/coder_config-ssh.md @@ -27,3 +27,4 @@ coder config-ssh [flags] ### SEE ALSO * [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation + diff --git a/docs/coder_envs.md b/docs/coder_envs.md index af394d16..176ab6b8 100644 --- a/docs/coder_envs.md +++ b/docs/coder_envs.md @@ -24,3 +24,4 @@ Perform operations on the Coder environments owned by the active user. * [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation * [coder envs ls](coder_envs_ls.md) - list all environments owned by the active user * [coder envs stop](coder_envs_stop.md) - stop Coder environments by name + diff --git a/docs/coder_envs_ls.md b/docs/coder_envs_ls.md index 49cd04dd..d4b78438 100644 --- a/docs/coder_envs_ls.md +++ b/docs/coder_envs_ls.md @@ -27,3 +27,4 @@ coder envs ls [flags] ### SEE ALSO * [coder envs](coder_envs.md) - Interact with Coder environments + diff --git a/docs/coder_envs_stop.md b/docs/coder_envs_stop.md index 1348a14c..b6cc6ec6 100644 --- a/docs/coder_envs_stop.md +++ b/docs/coder_envs_stop.md @@ -41,3 +41,4 @@ coder envs --user charlie@coder.com ls -o json \ ### SEE ALSO * [coder envs](coder_envs.md) - Interact with Coder environments + diff --git a/docs/coder_login.md b/docs/coder_login.md index bd3d9fb6..d4518229 100644 --- a/docs/coder_login.md +++ b/docs/coder_login.md @@ -25,3 +25,4 @@ coder login [Coder Enterprise URL eg. https://my.coder.domain/] [flags] ### SEE ALSO * [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation + diff --git a/docs/coder_logout.md b/docs/coder_logout.md index a41aa009..d7cfcef7 100644 --- a/docs/coder_logout.md +++ b/docs/coder_logout.md @@ -25,3 +25,4 @@ coder logout [flags] ### SEE ALSO * [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation + diff --git a/docs/coder_secrets.md b/docs/coder_secrets.md index b8178fd5..dec20226 100644 --- a/docs/coder_secrets.md +++ b/docs/coder_secrets.md @@ -26,3 +26,4 @@ Interact with secrets objects owned by the active user. * [coder secrets ls](coder_secrets_ls.md) - List all secrets owned by the active user * [coder secrets rm](coder_secrets_rm.md) - Remove one or more secrets by name * [coder secrets view](coder_secrets_view.md) - View a secret by name + diff --git a/docs/coder_secrets_create.md b/docs/coder_secrets_create.md index 3dfa1140..17255174 100644 --- a/docs/coder_secrets_create.md +++ b/docs/coder_secrets_create.md @@ -38,3 +38,4 @@ coder secrets create aws-credentials --from-file ./credentials.json ### SEE ALSO * [coder secrets](coder_secrets.md) - Interact with Coder Secrets + diff --git a/docs/coder_secrets_ls.md b/docs/coder_secrets_ls.md index e3e0ebc0..cbcd3dd4 100644 --- a/docs/coder_secrets_ls.md +++ b/docs/coder_secrets_ls.md @@ -26,3 +26,4 @@ coder secrets ls [flags] ### SEE ALSO * [coder secrets](coder_secrets.md) - Interact with Coder Secrets + diff --git a/docs/coder_secrets_rm.md b/docs/coder_secrets_rm.md index c8877d82..6c91b2bf 100644 --- a/docs/coder_secrets_rm.md +++ b/docs/coder_secrets_rm.md @@ -32,3 +32,4 @@ coder secrets rm mysql-password mysql-user ### SEE ALSO * [coder secrets](coder_secrets.md) - Interact with Coder Secrets + diff --git a/docs/coder_secrets_view.md b/docs/coder_secrets_view.md index 60fcaa4d..1a468017 100644 --- a/docs/coder_secrets_view.md +++ b/docs/coder_secrets_view.md @@ -32,3 +32,4 @@ coder secrets view mysql-password ### SEE ALSO * [coder secrets](coder_secrets.md) - Interact with Coder Secrets + diff --git a/docs/coder_sh.md b/docs/coder_sh.md index 8bc0d959..8bd80ac6 100644 --- a/docs/coder_sh.md +++ b/docs/coder_sh.md @@ -31,3 +31,4 @@ coder sh backend-env ### SEE ALSO * [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation + diff --git a/docs/coder_sync.md b/docs/coder_sync.md index 91098662..47949594 100644 --- a/docs/coder_sync.md +++ b/docs/coder_sync.md @@ -26,3 +26,4 @@ coder sync [local directory] [:] [flags] ### SEE ALSO * [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation + diff --git a/docs/coder_urls.md b/docs/coder_urls.md index 75f361f4..c725787b 100644 --- a/docs/coder_urls.md +++ b/docs/coder_urls.md @@ -24,3 +24,4 @@ Interact with environment DevURLs * [coder urls create](coder_urls_create.md) - Create a new devurl for an environment * [coder urls ls](coder_urls_ls.md) - List all DevURLs for an environment * [coder urls rm](coder_urls_rm.md) - Remove a dev url + diff --git a/docs/coder_urls_create.md b/docs/coder_urls_create.md index 5d613f56..5df9b96f 100644 --- a/docs/coder_urls_create.md +++ b/docs/coder_urls_create.md @@ -27,3 +27,4 @@ coder urls create [env_name] [port] [--access ] [--name ] [flags] ### SEE ALSO * [coder urls](coder_urls.md) - Interact with environment DevURLs + diff --git a/docs/coder_urls_ls.md b/docs/coder_urls_ls.md index 876210e9..bd01eb56 100644 --- a/docs/coder_urls_ls.md +++ b/docs/coder_urls_ls.md @@ -26,3 +26,4 @@ coder urls ls [environment_name] [flags] ### SEE ALSO * [coder urls](coder_urls.md) - Interact with environment DevURLs + diff --git a/docs/coder_urls_rm.md b/docs/coder_urls_rm.md index e19ccf30..ff961448 100644 --- a/docs/coder_urls_rm.md +++ b/docs/coder_urls_rm.md @@ -25,3 +25,4 @@ coder urls rm [environment_name] [port] [flags] ### SEE ALSO * [coder urls](coder_urls.md) - Interact with environment DevURLs + diff --git a/docs/coder_users.md b/docs/coder_users.md index 59a8c779..332d1824 100644 --- a/docs/coder_users.md +++ b/docs/coder_users.md @@ -22,3 +22,4 @@ Interact with Coder user accounts * [coder](coder.md) - coder provides a CLI for working with an existing Coder Enterprise installation * [coder users ls](coder_users_ls.md) - list all user accounts + diff --git a/docs/coder_users_ls.md b/docs/coder_users_ls.md index 99b00db2..e9624a83 100644 --- a/docs/coder_users_ls.md +++ b/docs/coder_users_ls.md @@ -33,3 +33,4 @@ coder users ls -o json | jq .[] | jq -r .email ### SEE ALSO * [coder users](coder_users.md) - Interact with Coder user accounts + diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 8917b22e..d00796cd 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -13,10 +13,11 @@ var verbose bool = false // Make constructs the "coder" root command func Make() *cobra.Command { app := &cobra.Command{ - Use: "coder", - Short: "coder provides a CLI for working with an existing Coder Enterprise installation", - SilenceErrors: true, - SilenceUsage: true, + Use: "coder", + Short: "coder provides a CLI for working with an existing Coder Enterprise installation", + SilenceErrors: true, + SilenceUsage: true, + DisableAutoGenTag: true, } app.AddCommand( diff --git a/internal/cmd/envs.go b/internal/cmd/envs.go index 50020eba..63d8f885 100644 --- a/internal/cmd/envs.go +++ b/internal/cmd/envs.go @@ -14,6 +14,15 @@ import ( "golang.org/x/xerrors" ) +const ( + defaultOrg = "default" + defaultImgTag = "latest" + defaultCPUCores float32 = 1 + defaultMemGB float32 = 1 + defaultDiskGB = 10 + defaultGPUs = 0 +) + func envsCommand() *cobra.Command { var outputFmt string var user string @@ -64,9 +73,9 @@ func envsCommand() *cobra.Command { lsCmd.Flags().StringVarP(&outputFmt, "output", "o", "human", "human | json") cmd.AddCommand(lsCmd) cmd.AddCommand(stopEnvCommand(&user)) - cmd.AddCommand(watchBuildLogCommand()) cmd.AddCommand(rebuildEnvCommand()) + cmd.AddCommand(createEnvCommand()) return cmd } @@ -125,3 +134,76 @@ coder envs --user charlie@coder.com ls -o json \ }, } } + +func createEnvCommand() *cobra.Command { + var ( + org string + img string + tag string + follow bool + ) + + cmd := &cobra.Command{ + Use: "create [environment_name]", + Short: "create a new environment.", + Args: cobra.ExactArgs(1), + // Don't unhide this command until we can pass image names instead of image id's. + Hidden: true, + Long: "Create a new environment under the active user.", + Example: `# create a new environment using default resource amounts +coder envs create --image 5f443b16-30652892427b955601330fa5 my-env-name + +# create a new environment using custom resource amounts +coder envs create --cpu 4 --disk 100 --memory 8 --image 5f443b16-30652892427b955601330fa5 my-env-name`, + RunE: func(cmd *cobra.Command, args []string) error { + if img == "" { + return xerrors.New("image id unset") + } + // ExactArgs(1) ensures our name value can't panic on an out of bounds. + createReq := &coder.CreateEnvironmentRequest{ + Name: args[0], + ImageID: img, + ImageTag: tag, + } + // We're explicitly ignoring errors for these because all of these flags + // have a non-zero-value default value set already. + createReq.CPUCores, _ = cmd.Flags().GetFloat32("cpu") + createReq.MemoryGB, _ = cmd.Flags().GetFloat32("memory") + createReq.DiskGB, _ = cmd.Flags().GetInt("disk") + createReq.GPUs, _ = cmd.Flags().GetInt("gpus") + + client, err := newClient() + if err != nil { + return err + } + + env, err := client.CreateEnvironment(cmd.Context(), org, *createReq) + if err != nil { + return xerrors.Errorf("create environment: %w", err) + } + + clog.LogSuccess( + "creating environment...", + clog.BlankLine, + clog.Tip(`run "coder envs watch-build %q" to trail the build logs`, args[0]), + ) + + if follow { + if err := trailBuildLogs(cmd.Context(), client, env.ID); err != nil { + return err + } + } + return nil + }, + } + cmd.Flags().StringVarP(&org, "org", "o", defaultOrg, "ID of the organization the environment should be created under.") + cmd.Flags().StringVarP(&tag, "tag", "t", defaultImgTag, "tag of the image the environment will be based off of.") + cmd.Flags().Float32P("cpu", "c", defaultCPUCores, "number of cpu cores the environment should be provisioned with.") + cmd.Flags().Float32P("memory", "m", defaultMemGB, "GB of RAM an environment should be provisioned with.") + cmd.Flags().IntP("disk", "d", defaultDiskGB, "GB of disk storage an environment should be provisioned with.") + cmd.Flags().IntP("gpus", "g", defaultGPUs, "number GPUs an environment should be provisioned with.") + cmd.Flags().StringVarP(&img, "image", "i", "", "ID of the image to base the environment off of.") + cmd.Flags().BoolVar(&follow, "follow", false, "follow buildlog after initiating rebuild") + cmd.MarkFlagRequired("image") + return cmd +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy