Skip to content

Commit 5d9ac64

Browse files
committed
Add parameters to the create screen
1 parent c85f7d2 commit 5d9ac64

File tree

9 files changed

+107
-32
lines changed

9 files changed

+107
-32
lines changed

coderd/database/dump.sql

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/migrations/000055_parameters.up.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CREATE TABLE template_version_parameters (
2-
template_version_id uuid not null references provisioner_jobs (id) on delete cascade,
2+
template_version_id uuid not null references template_versions (id) on delete cascade,
33
name text not null,
44
description text not null,
55
type text not null,

coderd/database/queries.sql.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/workspaceparameters.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ INSERT INTO
33
workspace_build_parameters (workspace_build_id, name, value)
44
SELECT
55
@workspace_build_id :: uuid AS workspace_build_id,
6-
unnset(@name :: text[]) AS name,
7-
unnset(@value :: text[]) AS value
6+
unnest(@name :: text[]) AS name,
7+
unnest(@value :: text[]) AS value
88
RETURNING *;
99

1010
-- name: GetWorkspaceBuildParameters :many

examples/templates/docker/main.tf

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ terraform {
22
required_providers {
33
coder = {
44
source = "coder/coder"
5-
version = "0.4.15"
5+
version = "0.5.0-pre"
66
}
77
docker = {
88
source = "kreuzwerker/docker"
@@ -54,15 +54,26 @@ resource "coder_app" "code-server" {
5454
}
5555
}
5656

57-
58-
variable "docker_image" {
59-
description = "Which Docker image would you like to use for your workspace?"
60-
# The codercom/enterprise-* images are only built for amd64
61-
default = "codercom/enterprise-base:ubuntu"
62-
validation {
63-
condition = contains(["codercom/enterprise-base:ubuntu", "codercom/enterprise-node:ubuntu",
64-
"codercom/enterprise-intellij:ubuntu", "codercom/enterprise-golang:ubuntu"], var.docker_image)
65-
error_message = "Invalid Docker image!"
57+
data "coder_parameter" "image" {
58+
name = "Image"
59+
description = "Select a Docker image to use for your workspace."
60+
mutable = true
61+
icon = "/emojis/1f5bc-fe0f.png"
62+
option {
63+
name = "Ubuntu"
64+
value = "codercom/enterprise-base:ubuntu"
65+
}
66+
option {
67+
name = "Node"
68+
value = "codercom/enterprise-node:ubuntu"
69+
}
70+
option {
71+
name = "Java"
72+
value = "codercom/enterprise-intellij:ubuntu"
73+
}
74+
option {
75+
name = "Go"
76+
value = "codercom/enterprise-golang:ubuntu"
6677
}
6778
}
6879

@@ -72,7 +83,7 @@ resource "docker_volume" "home_volume" {
7283

7384
resource "docker_container" "workspace" {
7485
count = data.coder_workspace.me.start_count
75-
image = var.docker_image
86+
image = data.coder_parameter.image.value
7687
# Uses lower() to avoid Docker restriction on container names.
7788
name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
7889
# Hostname makes the shell more user friendly: coder@my-workspace:~$
@@ -99,6 +110,6 @@ resource "coder_metadata" "container_info" {
99110

100111
item {
101112
key = "image"
102-
value = var.docker_image
113+
value = data.coder_parameter.image.value
103114
}
104115
}

site/src/api/api.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,22 @@ export const getTemplateVersion = async (versionId: string): Promise<TypesGen.Te
167167

168168
export const getTemplateVersionSchema = async (
169169
versionId: string,
170-
): Promise<TypesGen.ParameterSchema[]> => {
171-
const response = await axios.get<TypesGen.ParameterSchema[]>(
170+
): Promise<TypesGen.DeprecatedParameterSchema[]> => {
171+
const response = await axios.get<TypesGen.DeprecatedParameterSchema[]>(
172172
`/api/v2/templateversions/${versionId}/deprecated-schema`,
173173
)
174174
return response.data
175175
}
176176

177+
export const getTemplateVersionParameters = async (
178+
versionId: string,
179+
): Promise<TypesGen.TemplateVersionParameter[]> => {
180+
const response = await axios.get<TypesGen.TemplateVersionParameter[]>(
181+
`/api/v2/templateversions/${versionId}/parameters`,
182+
)
183+
return response.data
184+
}
185+
177186
export const getTemplateVersionResources = async (
178187
versionId: string,
179188
): Promise<TypesGen.WorkspaceResource[]> => {

site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const CreateWorkspacePage: FC = () => {
2424
const {
2525
templates,
2626
templateSchema,
27+
templateVersionParameters,
2728
selectedTemplate,
2829
getTemplateSchemaError,
2930
getTemplatesError,
@@ -44,6 +45,7 @@ const CreateWorkspacePage: FC = () => {
4445
templates={templates}
4546
selectedTemplate={selectedTemplate}
4647
templateSchema={templateSchema}
48+
templateParameters={templateVersionParameters}
4749
createWorkspaceErrors={{
4850
[CreateWorkspaceErrors.GET_TEMPLATES_ERROR]: getTemplatesError,
4951
[CreateWorkspaceErrors.GET_TEMPLATE_SCHEMA_ERROR]: getTemplateSchemaError,

site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { makeStyles } from "@material-ui/core/styles"
22
import TextField from "@material-ui/core/TextField"
33
import { ErrorSummary } from "components/ErrorSummary/ErrorSummary"
4+
import { WorkspaceParameter } from "components/WorkspaceParameter/WorkspaceParameter"
45
import { FormikContextType, FormikTouched, useFormik } from "formik"
56
import { FC, useState } from "react"
67
import * as Yup from "yup"
@@ -31,7 +32,8 @@ export interface CreateWorkspacePageViewProps {
3132
templateName: string
3233
templates?: TypesGen.Template[]
3334
selectedTemplate?: TypesGen.Template
34-
templateSchema?: TypesGen.ParameterSchema[]
35+
templateSchema?: TypesGen.DeprecatedParameterSchema[]
36+
templateParameters?: TypesGen.TemplateVersionParameter[]
3537
createWorkspaceErrors: Partial<Record<CreateWorkspaceErrors, Error | unknown>>
3638
onCancel: () => void
3739
onSubmit: (req: TypesGen.CreateWorkspaceRequest) => void
@@ -46,7 +48,9 @@ export const validationSchema = Yup.object({
4648
export const CreateWorkspacePageView: FC<React.PropsWithChildren<CreateWorkspacePageViewProps>> = (
4749
props,
4850
) => {
49-
const [parameterValues, setParameterValues] = useState<Record<string, string>>({})
51+
const [deprecatedParameterValues, setDeprecatedParameterValues] = useState<
52+
Record<string, string>
53+
>({})
5054
useStyles()
5155

5256
const form: FormikContextType<TypesGen.CreateWorkspaceRequest> =
@@ -63,11 +67,11 @@ export const CreateWorkspacePageView: FC<React.PropsWithChildren<CreateWorkspace
6367
throw new Error("No template schema loaded")
6468
}
6569

66-
const createRequests: TypesGen.CreateParameterRequest[] = []
70+
const createRequests: TypesGen.DeprecatedCreateParameterRequest[] = []
6771
props.templateSchema.forEach((schema) => {
6872
let value = schema.default_source_value
69-
if (schema.name in parameterValues) {
70-
value = parameterValues[schema.name]
73+
if (schema.name in deprecatedParameterValues) {
74+
value = deprecatedParameterValues[schema.name]
7175
}
7276
createRequests.push({
7377
name: schema.name,
@@ -149,8 +153,8 @@ export const CreateWorkspacePageView: FC<React.PropsWithChildren<CreateWorkspace
149153
disabled={form.isSubmitting}
150154
key={schema.id}
151155
onChange={(value) => {
152-
setParameterValues({
153-
...parameterValues,
156+
setDeprecatedParameterValues({
157+
...deprecatedParameterValues,
154158
[schema.name]: value,
155159
})
156160
}}
@@ -163,6 +167,12 @@ export const CreateWorkspacePageView: FC<React.PropsWithChildren<CreateWorkspace
163167
<FormFooter onCancel={props.onCancel} isLoading={props.creatingWorkspace} />
164168
</>
165169
)}
170+
171+
{props.selectedTemplate &&
172+
props.templateParameters &&
173+
props.templateParameters.map((parameter) => (
174+
<WorkspaceParameter templateParameter={parameter} key={parameter.name} />
175+
))}
166176
</Stack>
167177
</form>
168178
</FullPageForm>

site/src/xServices/createWorkspace/createWorkspaceXService.ts

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import { assign, createMachine } from "xstate"
2-
import { createWorkspace, getTemplates, getTemplateVersionSchema } from "../../api/api"
2+
import {
3+
createWorkspace,
4+
getTemplates,
5+
getTemplateVersionParameters,
6+
getTemplateVersionSchema,
7+
} from "../../api/api"
38
import {
49
CreateWorkspaceRequest,
5-
ParameterSchema,
10+
DeprecatedParameterSchema,
611
Template,
12+
TemplateVersionParameter,
713
Workspace,
814
} from "../../api/typesGenerated"
915

@@ -12,7 +18,9 @@ type CreateWorkspaceContext = {
1218
templateName: string
1319
templates?: Template[]
1420
selectedTemplate?: Template
15-
templateSchema?: ParameterSchema[]
21+
templateSchema?: DeprecatedParameterSchema[]
22+
templateVersionParameters?: TemplateVersionParameter[]
23+
templateVersionParametersError?: Error | unknown
1624
createWorkspaceRequest?: CreateWorkspaceRequest
1725
createdWorkspace?: Workspace
1826
createWorkspaceError?: Error | unknown
@@ -38,7 +46,10 @@ export const createWorkspaceMachine = createMachine(
3846
data: Template[]
3947
}
4048
getTemplateSchema: {
41-
data: ParameterSchema[]
49+
data: DeprecatedParameterSchema[]
50+
}
51+
getTemplateVersionParameters: {
52+
data: TemplateVersionParameter[]
4253
}
4354
createWorkspace: {
4455
data: Workspace
@@ -73,14 +84,28 @@ export const createWorkspaceMachine = createMachine(
7384
src: "getTemplateSchema",
7485
onDone: {
7586
actions: ["assignTemplateSchema"],
76-
target: "fillingParams",
87+
target: "gettingTemplateVersionParameters",
7788
},
7889
onError: {
7990
actions: ["assignGetTemplateSchemaError"],
8091
target: "error",
8192
},
8293
},
8394
},
95+
gettingTemplateVersionParameters: {
96+
entry: "clearTemplateVersionParametersError",
97+
invoke: {
98+
src: "getTemplateVersionParameters",
99+
onDone: {
100+
actions: ["assignTemplateVersionParameters"],
101+
target: "fillingParams",
102+
},
103+
onError: {
104+
actions: ["assignTemplateVersionParametersError"],
105+
target: "error",
106+
},
107+
},
108+
},
84109
fillingParams: {
85110
on: {
86111
CREATE_WORKSPACE: {
@@ -121,6 +146,15 @@ export const createWorkspaceMachine = createMachine(
121146

122147
return getTemplateVersionSchema(selectedTemplate.active_version_id)
123148
},
149+
getTemplateVersionParameters: (context) => {
150+
const { selectedTemplate } = context
151+
152+
if (!selectedTemplate) {
153+
throw new Error("No selected template")
154+
}
155+
156+
return getTemplateVersionParameters(selectedTemplate.active_version_id)
157+
},
124158
createWorkspace: (context) => {
125159
const { createWorkspaceRequest, organizationId } = context
126160

@@ -149,6 +183,15 @@ export const createWorkspaceMachine = createMachine(
149183
// CLI code: https://github.com/coder/coder/blob/main/cli/create.go#L152-L155
150184
templateSchema: (_, event) => event.data.filter((param) => param.allow_override_source),
151185
}),
186+
assignTemplateVersionParameters: assign({
187+
templateVersionParameters: (_, event) => event.data,
188+
}),
189+
assignTemplateVersionParametersError: assign({
190+
templateVersionParametersError: (_, event) => event.data,
191+
}),
192+
clearTemplateVersionParametersError: assign({
193+
templateVersionParametersError: (_) => undefined,
194+
}),
152195
assignCreateWorkspaceRequest: assign({
153196
createWorkspaceRequest: (_, event) => event.request,
154197
}),

0 commit comments

Comments
 (0)