Skip to content

Commit af2941b

Browse files
authored
feat: add is_prebuild_claim to distinguish post-claim provisioning (#17757)
Used in combination with coder/terraform-provider-coder#396 This is required by both #17475 and #17571 Operators may need to conditionalize their templates to perform certain operations once a prebuilt workspace has been claimed. This value will **only** be set once a claim takes place and a subsequent `terraform apply` occurs. Any `terraform apply` runs thereafter will be indistinguishable from a normal run on a workspace. --------- Signed-off-by: Danny Kopping <dannykopping@gmail.com>
1 parent 799a0ba commit af2941b

File tree

15 files changed

+478
-339
lines changed

15 files changed

+478
-339
lines changed

cli/testdata/coder_provisioner_list_--output_json.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"last_seen_at": "====[timestamp]=====",
88
"name": "test",
99
"version": "v0.0.0-devel",
10-
"api_version": "1.4",
10+
"api_version": "1.5",
1111
"provisioners": [
1212
"echo"
1313
],

coderd/provisionerdserver/provisionerdserver.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ func (s *server) acquireProtoJob(ctx context.Context, job database.ProvisionerJo
645645
WorkspaceBuildId: workspaceBuild.ID.String(),
646646
WorkspaceOwnerLoginType: string(owner.LoginType),
647647
WorkspaceOwnerRbacRoles: ownerRbacRoles,
648-
IsPrebuild: input.IsPrebuild,
648+
PrebuiltWorkspaceBuildStage: input.PrebuiltWorkspaceBuildStage,
649649
},
650650
LogLevel: input.LogLevel,
651651
},
@@ -2471,11 +2471,10 @@ type TemplateVersionImportJob struct {
24712471

24722472
// WorkspaceProvisionJob is the payload for the "workspace_provision" job type.
24732473
type WorkspaceProvisionJob struct {
2474-
WorkspaceBuildID uuid.UUID `json:"workspace_build_id"`
2475-
DryRun bool `json:"dry_run"`
2476-
IsPrebuild bool `json:"is_prebuild,omitempty"`
2477-
PrebuildClaimedByUser uuid.UUID `json:"prebuild_claimed_by,omitempty"`
2478-
LogLevel string `json:"log_level,omitempty"`
2474+
WorkspaceBuildID uuid.UUID `json:"workspace_build_id"`
2475+
DryRun bool `json:"dry_run"`
2476+
LogLevel string `json:"log_level,omitempty"`
2477+
PrebuiltWorkspaceBuildStage sdkproto.PrebuiltWorkspaceBuildStage `json:"prebuilt_workspace_stage,omitempty"`
24792478
}
24802479

24812480
// TemplateVersionDryRunJob is the payload for the "template_version_dry_run" job type.

coderd/provisionerdserver/provisionerdserver_test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ import (
2323
"storj.io/drpc"
2424

2525
"cdr.dev/slog/sloggers/slogtest"
26-
"github.com/coder/coder/v2/coderd/rbac"
2726
"github.com/coder/quartz"
2827
"github.com/coder/serpent"
2928

29+
"github.com/coder/coder/v2/coderd/rbac"
30+
3031
"github.com/coder/coder/v2/buildinfo"
3132
"github.com/coder/coder/v2/coderd/audit"
3233
"github.com/coder/coder/v2/coderd/database"
@@ -299,6 +300,10 @@ func TestAcquireJob(t *testing.T) {
299300
Transition: database.WorkspaceTransitionStart,
300301
Reason: database.BuildReasonInitiator,
301302
})
303+
var buildState sdkproto.PrebuiltWorkspaceBuildStage
304+
if prebuiltWorkspace {
305+
buildState = sdkproto.PrebuiltWorkspaceBuildStage_CREATE
306+
}
302307
_ = dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{
303308
ID: build.ID,
304309
OrganizationID: pd.OrganizationID,
@@ -308,8 +313,8 @@ func TestAcquireJob(t *testing.T) {
308313
FileID: file.ID,
309314
Type: database.ProvisionerJobTypeWorkspaceBuild,
310315
Input: must(json.Marshal(provisionerdserver.WorkspaceProvisionJob{
311-
WorkspaceBuildID: build.ID,
312-
IsPrebuild: prebuiltWorkspace,
316+
WorkspaceBuildID: build.ID,
317+
PrebuiltWorkspaceBuildStage: buildState,
313318
})),
314319
})
315320

@@ -380,7 +385,7 @@ func TestAcquireJob(t *testing.T) {
380385
WorkspaceOwnerRbacRoles: []*sdkproto.Role{{Name: rbac.RoleOrgMember(), OrgId: pd.OrganizationID.String()}, {Name: "member", OrgId: ""}, {Name: rbac.RoleOrgAuditor(), OrgId: pd.OrganizationID.String()}},
381386
}
382387
if prebuiltWorkspace {
383-
wantedMetadata.IsPrebuild = true
388+
wantedMetadata.PrebuiltWorkspaceBuildStage = sdkproto.PrebuiltWorkspaceBuildStage_CREATE
384389
}
385390

386391
slices.SortFunc(wantedMetadata.WorkspaceOwnerRbacRoles, func(a, b *sdkproto.Role) int {

coderd/workspaces.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ func createWorkspace(
713713
builder = builder.TemplateVersionPresetID(req.TemplateVersionPresetID)
714714
}
715715
if claimedWorkspace != nil {
716-
builder = builder.MarkPrebuildClaimedBy(owner.ID)
716+
builder = builder.MarkPrebuiltWorkspaceClaim()
717717
}
718718

719719
if req.EnableDynamicParameters && api.Experiments.Enabled(codersdk.ExperimentDynamicParameters) {

coderd/wsbuilder/wsbuilder.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/coder/coder/v2/coderd/rbac/policy"
1717
"github.com/coder/coder/v2/provisioner/terraform/tfparse"
1818
"github.com/coder/coder/v2/provisionersdk"
19+
sdkproto "github.com/coder/coder/v2/provisionersdk/proto"
1920

2021
"github.com/google/uuid"
2122
"github.com/sqlc-dev/pqtype"
@@ -76,8 +77,7 @@ type Builder struct {
7677
parameterValues *[]string
7778
templateVersionPresetParameterValues []database.TemplateVersionPresetParameter
7879

79-
prebuild bool
80-
prebuildClaimedBy uuid.UUID
80+
prebuiltWorkspaceBuildStage sdkproto.PrebuiltWorkspaceBuildStage
8181

8282
verifyNoLegacyParametersOnce bool
8383
}
@@ -174,15 +174,17 @@ func (b Builder) RichParameterValues(p []codersdk.WorkspaceBuildParameter) Build
174174
return b
175175
}
176176

177+
// MarkPrebuild indicates that a prebuilt workspace is being built.
177178
func (b Builder) MarkPrebuild() Builder {
178179
// nolint: revive
179-
b.prebuild = true
180+
b.prebuiltWorkspaceBuildStage = sdkproto.PrebuiltWorkspaceBuildStage_CREATE
180181
return b
181182
}
182183

183-
func (b Builder) MarkPrebuildClaimedBy(userID uuid.UUID) Builder {
184+
// MarkPrebuiltWorkspaceClaim indicates that a prebuilt workspace is being claimed.
185+
func (b Builder) MarkPrebuiltWorkspaceClaim() Builder {
184186
// nolint: revive
185-
b.prebuildClaimedBy = userID
187+
b.prebuiltWorkspaceBuildStage = sdkproto.PrebuiltWorkspaceBuildStage_CLAIM
186188
return b
187189
}
188190

@@ -322,10 +324,9 @@ func (b *Builder) buildTx(authFunc func(action policy.Action, object rbac.Object
322324

323325
workspaceBuildID := uuid.New()
324326
input, err := json.Marshal(provisionerdserver.WorkspaceProvisionJob{
325-
WorkspaceBuildID: workspaceBuildID,
326-
LogLevel: b.logLevel,
327-
IsPrebuild: b.prebuild,
328-
PrebuildClaimedByUser: b.prebuildClaimedBy,
327+
WorkspaceBuildID: workspaceBuildID,
328+
LogLevel: b.logLevel,
329+
PrebuiltWorkspaceBuildStage: b.prebuiltWorkspaceBuildStage,
329330
})
330331
if err != nil {
331332
return nil, nil, nil, BuildError{

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ require (
101101
github.com/coder/quartz v0.1.3
102102
github.com/coder/retry v1.5.1
103103
github.com/coder/serpent v0.10.0
104-
github.com/coder/terraform-provider-coder/v2 v2.4.0
104+
github.com/coder/terraform-provider-coder/v2 v2.4.1
105105
github.com/coder/websocket v1.8.13
106106
github.com/coder/wgtunnel v0.1.13-0.20240522110300-ade90dfb2da0
107107
github.com/coreos/go-oidc/v3 v3.14.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -925,8 +925,8 @@ github.com/coder/tailscale v1.1.1-0.20250422090654-5090e715905e h1:nope/SZfoLB9M
925925
github.com/coder/tailscale v1.1.1-0.20250422090654-5090e715905e/go.mod h1:1ggFFdHTRjPRu9Yc1yA7nVHBYB50w9Ce7VIXNqcW6Ko=
926926
github.com/coder/terraform-config-inspect v0.0.0-20250107175719-6d06d90c630e h1:JNLPDi2P73laR1oAclY6jWzAbucf70ASAvf5mh2cME0=
927927
github.com/coder/terraform-config-inspect v0.0.0-20250107175719-6d06d90c630e/go.mod h1:Gz/z9Hbn+4KSp8A2FBtNszfLSdT2Tn/uAKGuVqqWmDI=
928-
github.com/coder/terraform-provider-coder/v2 v2.4.0 h1:uuFmF03IyahAZLXEukOdmvV9hGfUMJSESD8+G5wkTcM=
929-
github.com/coder/terraform-provider-coder/v2 v2.4.0/go.mod h1:2kaBpn5k9ZWtgKq5k4JbkVZG9DzEqR4mJSmpdshcO+s=
928+
github.com/coder/terraform-provider-coder/v2 v2.4.1 h1:+HxLJVENJ+kvGhibQ0jbr8Evi6M857d9691ytxNbv90=
929+
github.com/coder/terraform-provider-coder/v2 v2.4.1/go.mod h1:2kaBpn5k9ZWtgKq5k4JbkVZG9DzEqR4mJSmpdshcO+s=
930930
github.com/coder/trivy v0.0.0-20250409153844-e6b004bc465a h1:yryP7e+IQUAArlycH4hQrjXQ64eRNbxsV5/wuVXHgME=
931931
github.com/coder/trivy v0.0.0-20250409153844-e6b004bc465a/go.mod h1:dDvq9axp3kZsT63gY2Znd1iwzfqDq3kXbQnccIrjRYY=
932932
github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE=

provisioner/terraform/provision.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,12 @@ func provisionEnv(
270270
"CODER_WORKSPACE_TEMPLATE_VERSION="+metadata.GetTemplateVersion(),
271271
"CODER_WORKSPACE_BUILD_ID="+metadata.GetWorkspaceBuildId(),
272272
)
273-
if metadata.GetIsPrebuild() {
273+
if metadata.GetPrebuiltWorkspaceBuildStage().IsPrebuild() {
274274
env = append(env, provider.IsPrebuildEnvironmentVariable()+"=true")
275275
}
276+
if metadata.GetPrebuiltWorkspaceBuildStage().IsPrebuiltWorkspaceClaim() {
277+
env = append(env, provider.IsPrebuildClaimEnvironmentVariable()+"=true")
278+
}
276279

277280
for key, value := range provisionersdk.AgentScriptEnv() {
278281
env = append(env, key+"="+value)

provisioner/terraform/provision_test.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525

2626
"cdr.dev/slog"
2727
"cdr.dev/slog/sloggers/slogtest"
28+
2829
"github.com/coder/coder/v2/codersdk/drpc"
2930
"github.com/coder/coder/v2/provisioner/terraform"
3031
"github.com/coder/coder/v2/provisionersdk"
@@ -977,7 +978,7 @@ func TestProvision(t *testing.T) {
977978
required_providers {
978979
coder = {
979980
source = "coder/coder"
980-
version = "2.3.0-pre2"
981+
version = ">= 2.4.1"
981982
}
982983
}
983984
}
@@ -994,7 +995,7 @@ func TestProvision(t *testing.T) {
994995
},
995996
Request: &proto.PlanRequest{
996997
Metadata: &proto.Metadata{
997-
IsPrebuild: true,
998+
PrebuiltWorkspaceBuildStage: proto.PrebuiltWorkspaceBuildStage_CREATE,
998999
},
9991000
},
10001001
Response: &proto.PlanComplete{
@@ -1008,6 +1009,44 @@ func TestProvision(t *testing.T) {
10081009
}},
10091010
},
10101011
},
1012+
{
1013+
Name: "is-prebuild-claim",
1014+
Files: map[string]string{
1015+
"main.tf": `terraform {
1016+
required_providers {
1017+
coder = {
1018+
source = "coder/coder"
1019+
version = ">= 2.4.1"
1020+
}
1021+
}
1022+
}
1023+
data "coder_workspace" "me" {}
1024+
resource "null_resource" "example" {}
1025+
resource "coder_metadata" "example" {
1026+
resource_id = null_resource.example.id
1027+
item {
1028+
key = "is_prebuild_claim"
1029+
value = data.coder_workspace.me.is_prebuild_claim
1030+
}
1031+
}
1032+
`,
1033+
},
1034+
Request: &proto.PlanRequest{
1035+
Metadata: &proto.Metadata{
1036+
PrebuiltWorkspaceBuildStage: proto.PrebuiltWorkspaceBuildStage_CLAIM,
1037+
},
1038+
},
1039+
Response: &proto.PlanComplete{
1040+
Resources: []*proto.Resource{{
1041+
Name: "example",
1042+
Type: "null_resource",
1043+
Metadata: []*proto.Resource_Metadata{{
1044+
Key: "is_prebuild_claim",
1045+
Value: "true",
1046+
}},
1047+
}},
1048+
},
1049+
},
10111050
}
10121051

10131052
// Remove unused cache dirs before running tests.

provisionerd/proto/version.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@ import "github.com/coder/coder/v2/apiversion"
1212
//
1313
// API v1.4:
1414
// - Add new field named `devcontainers` in the Agent.
15+
//
16+
// API v1.5:
17+
// - Add new field named `prebuilt_workspace_build_stage` enum in the Metadata message.
1518
const (
1619
CurrentMajor = 1
17-
CurrentMinor = 4
20+
CurrentMinor = 5
1821
)
1922

2023
// CurrentVersion is the current provisionerd API version.
2124
// Breaking changes to the provisionerd API **MUST** increment
2225
// CurrentMajor above.
26+
// Non-breaking changes to the provisionerd API **MUST** increment
27+
// CurrentMinor above.
2328
var CurrentVersion = apiversion.New(CurrentMajor, CurrentMinor)

0 commit comments

Comments
 (0)
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