Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c1012d2

Browse files
committed
Fix: echo provisioner
1 parent e032a36 commit c1012d2

File tree

5 files changed

+123
-36
lines changed

5 files changed

+123
-36
lines changed

coderd/coderdtest/authorize.go

+4
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ func AGPLRoutes(a *AuthTester) (map[string]string, map[string]RouteCheck) {
177177
AssertAction: rbac.ActionRead,
178178
AssertObject: rbac.ResourceTemplate.InOrg(a.Template.OrganizationID),
179179
},
180+
"GET:/api/v2/templateversions/{templateversion}/rich-parameters": {
181+
AssertAction: rbac.ActionRead,
182+
AssertObject: rbac.ResourceTemplate.InOrg(a.Template.OrganizationID),
183+
},
180184
"GET:/api/v2/templateversions/{templateversion}/resources": {
181185
AssertAction: rbac.ActionRead,
182186
AssertObject: rbac.ResourceTemplate.InOrg(a.Template.OrganizationID),

coderd/provisionerdserver/provisionerdserver.go

+59-4
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,18 @@ func (server *Server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Ac
181181
return nil, failJob(fmt.Sprintf("convert workspace transition: %s", err))
182182
}
183183

184+
workspaceBuildParameters, err := server.Database.GetWorkspaceBuildParameters(ctx, workspaceBuild.ID)
185+
if err != nil {
186+
return nil, failJob(fmt.Sprintf("get workspace build parameters: %s", err))
187+
}
188+
184189
protoJob.Type = &proto.AcquiredJob_WorkspaceBuild_{
185190
WorkspaceBuild: &proto.AcquiredJob_WorkspaceBuild{
186-
WorkspaceBuildId: workspaceBuild.ID.String(),
187-
WorkspaceName: workspace.Name,
188-
State: workspaceBuild.ProvisionerState,
189-
ParameterValues: protoParameters,
191+
WorkspaceBuildId: workspaceBuild.ID.String(),
192+
WorkspaceName: workspace.Name,
193+
State: workspaceBuild.ProvisionerState,
194+
ParameterValues: protoParameters,
195+
RichParameterValues: convertRichParameterValues(workspaceBuildParameters),
190196
Metadata: &sdkproto.Provision_Metadata{
191197
CoderUrl: server.AccessURL.String(),
192198
WorkspaceTransition: transition,
@@ -597,6 +603,12 @@ func (server *Server) CompleteJob(ctx context.Context, completed *proto.Complete
597603

598604
switch jobType := completed.Type.(type) {
599605
case *proto.CompletedJob_TemplateImport_:
606+
var input TemplateVersionImportJob
607+
err = json.Unmarshal(job.Input, &input)
608+
if err != nil {
609+
return nil, xerrors.Errorf("unmarshal job data: %w", err)
610+
}
611+
600612
for transition, resources := range map[database.WorkspaceTransition][]*sdkproto.Resource{
601613
database.WorkspaceTransitionStart: jobType.TemplateImport.StartResources,
602614
database.WorkspaceTransitionStop: jobType.TemplateImport.StopResources,
@@ -615,6 +627,34 @@ func (server *Server) CompleteJob(ctx context.Context, completed *proto.Complete
615627
}
616628
}
617629

630+
server.Logger.Info(ctx, "template import !", slog.F("template_import", jobType.TemplateImport.String()))
631+
for _, richParameter := range jobType.TemplateImport.RichParameters {
632+
server.Logger.Info(ctx, "inserting template import job parameter",
633+
slog.F("job_id", job.ID.String()),
634+
slog.F("parameter_name", richParameter.Name),
635+
)
636+
options, err := json.Marshal(richParameter.Options)
637+
if err != nil {
638+
return nil, xerrors.Errorf("marshal parameter options: %w", err)
639+
}
640+
_, err = server.Database.InsertTemplateVersionParameter(ctx, database.InsertTemplateVersionParameterParams{
641+
TemplateVersionID: input.TemplateVersionID,
642+
Name: richParameter.Name,
643+
Description: richParameter.Description,
644+
Type: richParameter.Type,
645+
Mutable: richParameter.Mutable,
646+
DefaultValue: richParameter.DefaultValue,
647+
Icon: richParameter.Icon,
648+
Options: options,
649+
ValidationRegex: richParameter.ValidationRegex,
650+
ValidationMin: richParameter.ValidationMin,
651+
ValidationMax: richParameter.ValidationMax,
652+
})
653+
if err != nil {
654+
return nil, xerrors.Errorf("insert parameter: %w", err)
655+
}
656+
}
657+
618658
err = server.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
619659
ID: jobID,
620660
UpdatedAt: database.Now(),
@@ -1056,6 +1096,17 @@ func convertLogSource(logSource proto.LogSource) (database.LogSource, error) {
10561096
}
10571097
}
10581098

1099+
func convertRichParameterValues(workspaceBuildParameters []database.WorkspaceBuildParameter) []*sdkproto.RichParameterValue {
1100+
protoParameters := make([]*sdkproto.RichParameterValue, len(workspaceBuildParameters))
1101+
for i, buildParameter := range workspaceBuildParameters {
1102+
protoParameters[i] = &sdkproto.RichParameterValue{
1103+
Name: buildParameter.Name,
1104+
Value: buildParameter.Value,
1105+
}
1106+
}
1107+
return protoParameters
1108+
}
1109+
10591110
func convertComputedParameterValues(parameters []parameter.ComputedValue) ([]*sdkproto.ParameterValue, error) {
10601111
protoParameters := make([]*sdkproto.ParameterValue, len(parameters))
10611112
for i, computedParameter := range parameters {
@@ -1113,6 +1164,10 @@ func auditActionFromTransition(transition database.WorkspaceTransition) database
11131164
}
11141165
}
11151166

1167+
type TemplateVersionImportJob struct {
1168+
TemplateVersionID uuid.UUID `json:"template_version_id"`
1169+
}
1170+
11161171
// WorkspaceProvisionJob is the payload for the "workspace_provision" job type.
11171172
type WorkspaceProvisionJob struct {
11181173
WorkspaceBuildID uuid.UUID `json:"workspace_build_id"`

coderd/templateversions.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,14 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
11961196
}
11971197
}
11981198

1199+
templateVersionID := uuid.New()
1200+
jobInput, err := json.Marshal(provisionerdserver.TemplateVersionImportJob{
1201+
TemplateVersionID: templateVersionID,
1202+
})
1203+
if err != nil {
1204+
return xerrors.Errorf("marshal job input: %w", err)
1205+
}
1206+
11991207
provisionerJob, err = tx.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
12001208
ID: jobID,
12011209
CreatedAt: database.Now(),
@@ -1206,7 +1214,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
12061214
StorageMethod: database.ProvisionerStorageMethodFile,
12071215
FileID: file.ID,
12081216
Type: database.ProvisionerJobTypeTemplateVersionImport,
1209-
Input: []byte{'{', '}'},
1217+
Input: jobInput,
12101218
Tags: tags,
12111219
})
12121220
if err != nil {
@@ -1226,7 +1234,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
12261234
}
12271235

12281236
templateVersion, err = tx.InsertTemplateVersion(ctx, database.InsertTemplateVersionParams{
1229-
ID: uuid.New(),
1237+
ID: templateVersionID,
12301238
TemplateID: templateID,
12311239
OrganizationID: organization.ID,
12321240
CreatedAt: database.Now(),

coderd/workspacebuilds_test.go

+38-20
Original file line numberDiff line numberDiff line change
@@ -638,32 +638,50 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
638638

639639
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
640640
user := coderdtest.CreateFirstUser(t, client)
641-
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
642-
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
643-
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
644-
645-
expected := []codersdk.WorkspaceBuildParameter{
646-
{
647-
Name: "first_parameter",
648-
Value: "1",
649-
}, {
650-
Name: "second_parameter",
651-
Value: "2",
652-
},
653-
}
654-
655-
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
656-
cwr.RichParameterValues = expected
641+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
642+
Parse: echo.ParseComplete,
643+
ProvisionPlan: []*proto.Provision_Response{
644+
{
645+
Type: &proto.Provision_Response_Complete{
646+
Complete: &proto.Provision_Complete{
647+
Parameters: []*proto.RichParameter{
648+
{
649+
Name: "first_parameter",
650+
Description: "This is first parameter",
651+
},
652+
{
653+
Name: "second_parameter",
654+
Description: "This is second parameter",
655+
},
656+
},
657+
},
658+
},
659+
}},
657660
})
661+
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
658662

659663
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
660664
defer cancel()
661665

662-
_, err := client.WorkspaceBuild(ctx, workspace.LatestBuild.ID)
663-
require.NoError(t, err)
664-
665666
richParameters, err := client.TemplateVersionRichParameters(ctx, version.ID)
666667
require.NoError(t, err)
667668
require.Len(t, richParameters, 2)
668-
require.ElementsMatch(t, expected, richParameters)
669+
require.Equal(t, richParameters[0].Name, "first_parameter")
670+
require.Equal(t, richParameters[1].Name, "second_parameter")
671+
672+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
673+
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
674+
cwr.RichParameterValues = []codersdk.WorkspaceBuildParameter{
675+
{
676+
Name: "first_parameter",
677+
Value: "1",
678+
},
679+
{
680+
Name: "second_parameter",
681+
Value: "2",
682+
},
683+
}
684+
})
685+
_, err = client.WorkspaceBuild(ctx, workspace.LatestBuild.ID)
686+
require.NoError(t, err)
669687
}

provisionerd/runner/runner.go

+12-10
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ func (r *Runner) do(ctx context.Context) (*proto.CompletedJob, *proto.FailedJob)
434434
slog.F("workspace_name", jobType.WorkspaceBuild.WorkspaceName),
435435
slog.F("state_length", len(jobType.WorkspaceBuild.State)),
436436
slog.F("parameters", jobType.WorkspaceBuild.ParameterValues),
437+
slog.F("rich_parameter_values", jobType.WorkspaceBuild.RichParameterValues),
437438
)
438439
return r.runWorkspaceBuild(ctx)
439440
default:
@@ -566,7 +567,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
566567
Stage: "Detecting persistent resources",
567568
CreatedAt: time.Now().UnixMilli(),
568569
})
569-
startResources, err := r.runTemplateImportProvision(ctx, updateResponse.ParameterValues, &sdkproto.Provision_Metadata{
570+
startResources, parameters, err := r.runTemplateImportProvision(ctx, updateResponse.ParameterValues, &sdkproto.Provision_Metadata{
570571
CoderUrl: r.job.GetTemplateImport().Metadata.CoderUrl,
571572
WorkspaceTransition: sdkproto.WorkspaceTransition_START,
572573
})
@@ -581,7 +582,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
581582
Stage: "Detecting ephemeral resources",
582583
CreatedAt: time.Now().UnixMilli(),
583584
})
584-
stopResources, err := r.runTemplateImportProvision(ctx, updateResponse.ParameterValues, &sdkproto.Provision_Metadata{
585+
stopResources, _, err := r.runTemplateImportProvision(ctx, updateResponse.ParameterValues, &sdkproto.Provision_Metadata{
585586
CoderUrl: r.job.GetTemplateImport().Metadata.CoderUrl,
586587
WorkspaceTransition: sdkproto.WorkspaceTransition_STOP,
587588
})
@@ -595,6 +596,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
595596
TemplateImport: &proto.CompletedJob_TemplateImport{
596597
StartResources: startResources,
597598
StopResources: stopResources,
599+
RichParameters: parameters,
598600
},
599601
},
600602
}, nil
@@ -646,7 +648,7 @@ func (r *Runner) runTemplateImportParse(ctx context.Context) ([]*sdkproto.Parame
646648
// Performs a dry-run provision when importing a template.
647649
// This is used to detect resources that would be provisioned
648650
// for a workspace in various states.
649-
func (r *Runner) runTemplateImportProvision(ctx context.Context, values []*sdkproto.ParameterValue, metadata *sdkproto.Provision_Metadata) ([]*sdkproto.Resource, error) {
651+
func (r *Runner) runTemplateImportProvision(ctx context.Context, values []*sdkproto.ParameterValue, metadata *sdkproto.Provision_Metadata) ([]*sdkproto.Resource, []*sdkproto.RichParameter, error) {
650652
ctx, span := r.startTrace(ctx, tracing.FuncName())
651653
defer span.End()
652654

@@ -661,7 +663,7 @@ func (r *Runner) runTemplateImportProvision(ctx context.Context, values []*sdkpr
661663
// to send the cancel to the provisioner
662664
stream, err := r.provisioner.Provision(ctx)
663665
if err != nil {
664-
return nil, xerrors.Errorf("provision: %w", err)
666+
return nil, nil, xerrors.Errorf("provision: %w", err)
665667
}
666668
defer stream.Close()
667669
go func() {
@@ -688,13 +690,13 @@ func (r *Runner) runTemplateImportProvision(ctx context.Context, values []*sdkpr
688690
},
689691
})
690692
if err != nil {
691-
return nil, xerrors.Errorf("start provision: %w", err)
693+
return nil, nil, xerrors.Errorf("start provision: %w", err)
692694
}
693695

694696
for {
695697
msg, err := stream.Recv()
696698
if err != nil {
697-
return nil, xerrors.Errorf("recv import provision: %w", err)
699+
return nil, nil, xerrors.Errorf("recv import provision: %w", err)
698700
}
699701
switch msgType := msg.Type.(type) {
700702
case *sdkproto.Provision_Response_Log:
@@ -715,7 +717,7 @@ func (r *Runner) runTemplateImportProvision(ctx context.Context, values []*sdkpr
715717
slog.F("error", msgType.Complete.Error),
716718
)
717719

718-
return nil, xerrors.New(msgType.Complete.Error)
720+
return nil, nil, xerrors.New(msgType.Complete.Error)
719721
}
720722

721723
r.logger.Info(context.Background(), "parse dry-run provision successful",
@@ -724,9 +726,9 @@ func (r *Runner) runTemplateImportProvision(ctx context.Context, values []*sdkpr
724726
slog.F("state_length", len(msgType.Complete.State)),
725727
)
726728

727-
return msgType.Complete.Resources, nil
729+
return msgType.Complete.Resources, msgType.Complete.Parameters, nil
728730
default:
729-
return nil, xerrors.Errorf("invalid message type %q received from provisioner",
731+
return nil, nil, xerrors.Errorf("invalid message type %q received from provisioner",
730732
reflect.TypeOf(msg.Type).String())
731733
}
732734
}
@@ -765,7 +767,7 @@ func (r *Runner) runTemplateDryRun(ctx context.Context) (*proto.CompletedJob, *p
765767
}
766768

767769
// Run the template import provision task since it's already a dry run.
768-
resources, err := r.runTemplateImportProvision(ctx,
770+
resources, _, err := r.runTemplateImportProvision(ctx,
769771
r.job.GetTemplateDryRun().GetParameterValues(),
770772
metadata,
771773
)

0 commit comments

Comments
 (0)