Skip to content

Commit 4466836

Browse files
committed
Handle multiple states correctly when provisioning a project
1 parent e53f0be commit 4466836

File tree

3 files changed

+62
-16
lines changed

3 files changed

+62
-16
lines changed

coderd/parameter/compute.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ import (
1111
"github.com/coder/coder/database"
1212
)
1313

14+
const (
15+
CoderUsername = "coder_username"
16+
CoderWorkspaceTransition = "coder_workspace_transition"
17+
)
18+
1419
// ComputeScope targets identifiers to pull parameters from.
1520
type ComputeScope struct {
1621
ProjectImportJobID uuid.UUID

provisionerd/provisionerd.go

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,23 @@ import (
1919
"golang.org/x/xerrors"
2020

2121
"cdr.dev/slog"
22+
"github.com/coder/coder/coderd/parameter"
2223
"github.com/coder/coder/provisionerd/proto"
2324
sdkproto "github.com/coder/coder/provisionersdk/proto"
2425
"github.com/coder/retry"
2526
)
2627

28+
const (
29+
missingParameterErrorText = "missing parameter"
30+
)
31+
32+
// IsMissingParameterError returns whether the error message provided
33+
// is a missing parameter error. This can indicate to consumers that
34+
// they should check parameters.
35+
func IsMissingParameterError(err string) bool {
36+
return strings.Contains(err, missingParameterErrorText)
37+
}
38+
2739
// Dialer represents the function to create a daemon client connection.
2840
type Dialer func(ctx context.Context) (proto.DRPCProvisionerDaemonClient, error)
2941

@@ -352,32 +364,53 @@ func (p *provisionerDaemon) runProjectImport(ctx context.Context, provisioner sd
352364
valueByName[parameterValue.Name] = parameterValue
353365
}
354366
for _, parameterSchema := range parameterSchemas {
367+
if parameterSchema.Name == parameter.CoderWorkspaceTransition {
368+
// Hardcode the workspace transition variable. We'll
369+
// make it do stuff later!
370+
continue
371+
}
355372
_, ok := valueByName[parameterSchema.Name]
356373
if !ok {
357-
p.cancelActiveJobf("missing parameter: %s", parameterSchema.Name)
374+
p.cancelActiveJobf("%s: %s", missingParameterErrorText, parameterSchema.Name)
358375
return
359376
}
360377
}
378+
// Checks if the schema has defined a workspace transition variable.
379+
// If not, we don't need to check for resources provisioned in a stopped state.
380+
hasWorkspaceTransition := false
381+
for _, parameterSchema := range parameterSchemas {
382+
if parameterSchema.Name != parameter.CoderWorkspaceTransition {
383+
continue
384+
}
385+
hasWorkspaceTransition = true
386+
break
387+
}
361388

362-
startResources, err := p.runProjectImportProvision(ctx, provisioner, job, append(updateResponse.ParameterValues, &sdkproto.ParameterValue{
363-
DestinationScheme: sdkproto.ParameterDestination_PROVISIONER_VARIABLE,
364-
// TODO: Make this a constant higher-up in the stack.
365-
Name: "coder_workspace_transition",
366-
Value: "start",
367-
}))
368-
if err != nil {
369-
p.cancelActiveJobf("project import provision for start: %s", err)
370-
return
389+
startParameters := updateResponse.ParameterValues
390+
if hasWorkspaceTransition {
391+
startParameters = append(updateResponse.ParameterValues, &sdkproto.ParameterValue{
392+
DestinationScheme: sdkproto.ParameterDestination_PROVISIONER_VARIABLE,
393+
Name: parameter.CoderWorkspaceTransition,
394+
Value: "start",
395+
})
371396
}
372-
stopResources, err := p.runProjectImportProvision(ctx, provisioner, job, append(updateResponse.ParameterValues, &sdkproto.ParameterValue{
373-
DestinationScheme: sdkproto.ParameterDestination_PROVISIONER_VARIABLE,
374-
Name: "coder_workspace_transition",
375-
Value: "stop",
376-
}))
397+
startResources, err := p.runProjectImportProvision(ctx, provisioner, job, startParameters)
377398
if err != nil {
378399
p.cancelActiveJobf("project import provision for start: %s", err)
379400
return
380401
}
402+
stopResources := startResources
403+
if hasWorkspaceTransition {
404+
stopResources, err = p.runProjectImportProvision(ctx, provisioner, job, append(updateResponse.ParameterValues, &sdkproto.ParameterValue{
405+
DestinationScheme: sdkproto.ParameterDestination_PROVISIONER_VARIABLE,
406+
Name: "coder_workspace_transition",
407+
Value: "stop",
408+
}))
409+
if err != nil {
410+
p.cancelActiveJobf("project import provision for start: %s", err)
411+
return
412+
}
413+
}
381414

382415
_, err = p.client.CompleteJob(ctx, &proto.CompletedJob{
383416
JobId: job.JobId,

provisionerd/provisionerd_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"cdr.dev/slog"
2222
"cdr.dev/slog/sloggers/slogtest"
2323

24+
"github.com/coder/coder/coderd/parameter"
2425
"github.com/coder/coder/provisionerd"
2526
"github.com/coder/coder/provisionerd/proto"
2627
"github.com/coder/coder/provisionersdk"
@@ -195,6 +196,7 @@ func TestProvisionerd(t *testing.T) {
195196
didComplete atomic.Bool
196197
didLog atomic.Bool
197198
didAcquireJob atomic.Bool
199+
didDryRun atomic.Bool
198200
)
199201
completeChan := make(chan struct{})
200202
closer := createProvisionerd(t, func(ctx context.Context) (proto.DRPCProvisionerDaemonClient, error) {
@@ -247,14 +249,19 @@ func TestProvisionerd(t *testing.T) {
247249
err = stream.Send(&sdkproto.Parse_Response{
248250
Type: &sdkproto.Parse_Response_Complete{
249251
Complete: &sdkproto.Parse_Complete{
250-
ParameterSchemas: []*sdkproto.ParameterSchema{},
252+
ParameterSchemas: []*sdkproto.ParameterSchema{{
253+
Name: parameter.CoderWorkspaceTransition,
254+
}},
251255
},
252256
},
253257
})
254258
require.NoError(t, err)
255259
return nil
256260
},
257261
provision: func(request *sdkproto.Provision_Request, stream sdkproto.DRPCProvisioner_ProvisionStream) error {
262+
if request.DryRun {
263+
didDryRun.Store(true)
264+
}
258265
err := stream.Send(&sdkproto.Provision_Response{
259266
Type: &sdkproto.Provision_Response_Log{
260267
Log: &sdkproto.Log{
@@ -280,6 +287,7 @@ func TestProvisionerd(t *testing.T) {
280287
<-completeChan
281288
require.True(t, didLog.Load())
282289
require.True(t, didComplete.Load())
290+
require.True(t, didDryRun.Load())
283291
require.NoError(t, closer.Close())
284292
})
285293

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