From 7124ab0ca59caa19a335fa060a90caca9b161923 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 23 Sep 2021 21:01:42 -0400 Subject: [PATCH 1/2] Allow setting workspace thresholds from the api --- coder-sdk/org.go | 1 + coder-sdk/workspace.go | 15 ++++---- internal/cmd/workspaces.go | 70 +++++++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/coder-sdk/org.go b/coder-sdk/org.go index 0922d229..360a9531 100644 --- a/coder-sdk/org.go +++ b/coder-sdk/org.go @@ -72,6 +72,7 @@ type UpdateOrganizationReq struct { AutoOffThreshold *Duration `json:"auto_off_threshold"` CPUProvisioningRate *float32 `json:"cpu_provisioning_rate"` MemoryProvisioningRate *float32 `json:"memory_provisioning_rate"` + AllowWorkspaceAutoOff *bool `json:"workspace_auto_off"` } // UpdateOrganization applys a partial update of an Organization resource. diff --git a/coder-sdk/workspace.go b/coder-sdk/workspace.go index e30c5c58..c68275cd 100644 --- a/coder-sdk/workspace.go +++ b/coder-sdk/workspace.go @@ -211,13 +211,14 @@ func (c *DefaultClient) StopWorkspace(ctx context.Context, workspaceID string) e // UpdateWorkspaceReq defines the update operation, only setting // nil-fields. type UpdateWorkspaceReq struct { - ImageID *string `json:"image_id"` - ImageTag *string `json:"image_tag"` - CPUCores *float32 `json:"cpu_cores"` - MemoryGB *float32 `json:"memory_gb"` - DiskGB *int `json:"disk_gb"` - GPUs *int `json:"gpus"` - TemplateID *string `json:"template_id"` + ImageID *string `json:"image_id"` + ImageTag *string `json:"image_tag"` + CPUCores *float32 `json:"cpu_cores"` + MemoryGB *float32 `json:"memory_gb"` + DiskGB *int `json:"disk_gb"` + GPUs *int `json:"gpus"` + TemplateID *string `json:"template_id"` + WorkspaceAutoOffThreshold *Duration `json:"workspace_auto_off_threshold"` } // RebuildWorkspace requests that the given workspaceID is rebuilt with no changes to its specification. diff --git a/internal/cmd/workspaces.go b/internal/cmd/workspaces.go index 8ac30565..a8ad9cce 100644 --- a/internal/cmd/workspaces.go +++ b/internal/cmd/workspaces.go @@ -729,16 +729,17 @@ coder workspaces create-from-config --name="dev-env" --filepath coder.yaml`, func editWorkspaceCmd() *cobra.Command { var ( - org string - img string - tag string - cpu float32 - memory float32 - disk int - gpus int - follow bool - user string - force bool + org string + img string + tag string + cpu float32 + memory float32 + disk int + gpus int + follow bool + user string + autoOffDuration time.Duration + force bool ) cmd := &cobra.Command{ @@ -773,16 +774,24 @@ coder workspaces edit back-end-workspace --disk 20`, return xerrors.New("org is required for multi-org members") } + // Only update this field if the user specifically requested it via a flag. + var workspaceAutoOff *coder.Duration + if cmd.Flags().Changed("auto-off") { + tmp := coder.Duration(autoOffDuration) + workspaceAutoOff = &tmp + } + req, err := buildUpdateReq(ctx, client, updateConf{ - cpu: cpu, - memGB: memory, - diskGB: disk, - gpus: gpus, - workspace: workspace, - user: user, - image: img, - imageTag: tag, - orgName: org, + cpu: cpu, + memGB: memory, + diskGB: disk, + gpus: gpus, + workspace: workspace, + user: user, + image: img, + imageTag: tag, + orgName: org, + workspaceAutoOffDuration: workspaceAutoOff, }) if err != nil { return err @@ -820,6 +829,8 @@ coder workspaces edit back-end-workspace --disk 20`, return nil }, } + cmd.Flags().DurationVar(&autoOffDuration, "auto-off", 0, "Sets the workspace's auto-off setting. This only works if the organization has this feature enabled. "+ + "Set to '-1' to disable auto-off, and '0' to default to the organization's setting.") cmd.Flags().StringVarP(&org, "org", "o", "", "name of the organization the workspace should be created under.") cmd.Flags().StringVarP(&img, "image", "i", "", "name of the image you want the workspace to be based off of.") cmd.Flags().StringVarP(&tag, "tag", "t", "latest", "image tag of the image you want to base the workspace off of.") @@ -889,15 +900,16 @@ func rmWorkspacesCmd() *cobra.Command { } type updateConf struct { - cpu float32 - memGB float32 - diskGB int - gpus int - workspace *coder.Workspace - user string - image string - imageTag string - orgName string + cpu float32 + memGB float32 + diskGB int + gpus int + workspace *coder.Workspace + user string + image string + imageTag string + orgName string + workspaceAutoOffDuration *coder.Duration } func buildUpdateReq(ctx context.Context, client coder.Client, conf updateConf) (*coder.UpdateWorkspaceReq, error) { @@ -988,6 +1000,8 @@ func buildUpdateReq(ctx context.Context, client coder.Client, conf updateConf) ( } else { updateReq.ImageTag = &conf.imageTag } + + updateReq.WorkspaceAutoOffThreshold = conf.workspaceAutoOffDuration return &updateReq, nil } From 108bb689c0067a2eca583f6e8a5e69e36b8f2ff4 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 23 Sep 2021 21:37:31 -0400 Subject: [PATCH 2/2] Also allow threshold on create workspace --- coder-sdk/workspace.go | 3 +++ internal/cmd/workspaces.go | 32 ++++++++++++++++++-------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/coder-sdk/workspace.go b/coder-sdk/workspace.go index c68275cd..b0c18833 100644 --- a/coder-sdk/workspace.go +++ b/coder-sdk/workspace.go @@ -89,6 +89,9 @@ type CreateWorkspaceRequest struct { Namespace string `json:"namespace"` EnableAutoStart bool `json:"autostart_enabled"` + // WorkspaceAutoOffThreshold is optional, 0 defaults to the org settings + WorkspaceAutoOffThreshold Duration `json:"workspace_auto_off_threshold"` + // ForUserID is an optional param to create a workspace for another user // other than the requester. This only works for admins and site managers. ForUserID string `json:"for_user_id,omitempty"` diff --git a/internal/cmd/workspaces.go b/internal/cmd/workspaces.go index a8ad9cce..2636326e 100644 --- a/internal/cmd/workspaces.go +++ b/internal/cmd/workspaces.go @@ -397,7 +397,8 @@ func createWorkspaceCmd() *cobra.Command { useCVM bool providerName string enableAutostart bool - forUser string // Optional + forUser string // Optional + autoOffDuration time.Duration // Optional ) cmd := &cobra.Command{ @@ -468,19 +469,20 @@ coder workspaces create my-new-powerful-workspace --cpu 12 --disk 100 --memory 1 // ExactArgs(1) ensures our name value can't panic on an out of bounds. createReq := &coder.CreateWorkspaceRequest{ - Name: args[0], - ImageID: importedImg.ID, - OrgID: importedImg.OrganizationID, - ImageTag: tag, - CPUCores: cpu, - MemoryGB: memory, - DiskGB: disk, - GPUs: gpus, - UseContainerVM: useCVM, - ResourcePoolID: provider.ID, - Namespace: provider.DefaultNamespace, - EnableAutoStart: enableAutostart, - ForUserID: forUser, + Name: args[0], + ImageID: importedImg.ID, + OrgID: importedImg.OrganizationID, + ImageTag: tag, + CPUCores: cpu, + MemoryGB: memory, + DiskGB: disk, + GPUs: gpus, + UseContainerVM: useCVM, + ResourcePoolID: provider.ID, + Namespace: provider.DefaultNamespace, + EnableAutoStart: enableAutostart, + ForUserID: forUser, + WorkspaceAutoOffThreshold: coder.Duration(autoOffDuration), } // if any of these defaulted to their zero value we provision @@ -519,6 +521,8 @@ coder workspaces create my-new-powerful-workspace --cpu 12 --disk 100 --memory 1 return nil }, } + cmd.Flags().DurationVar(&autoOffDuration, "auto-off", 0, "Sets the workspace's auto-off setting. This only works if the organization has this feature enabled. "+ + "Set to '-1' to disable auto-off, and '0' to default to the organization's setting.") cmd.Flags().StringVarP(&org, "org", "o", "", "name of the organization the workspace should be created under.") cmd.Flags().StringVarP(&tag, "tag", "t", defaultImgTag, "tag of the image the workspace will be based off of.") cmd.Flags().Float32VarP(&cpu, "cpu", "c", 0, "number of cpu cores the workspace should be provisioned with.")