diff --git a/coderd/prebuilds/controller.go b/coderd/prebuilds/controller.go index 04ed77b47c..473e16c508 100644 --- a/coderd/prebuilds/controller.go +++ b/coderd/prebuilds/controller.go @@ -5,6 +5,13 @@ import ( "crypto/rand" "encoding/base32" "fmt" + "math" + mrand "math/rand" + "strings" + "time" + + "golang.org/x/exp/slices" + "github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/database/dbtime" "github.com/coder/coder/v2/coderd/database/provisionerjobs" @@ -12,19 +19,16 @@ import ( "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac/policy" "github.com/coder/coder/v2/coderd/wsbuilder" - "golang.org/x/exp/slices" - "math" - mrand "math/rand" - "strings" - "time" + "github.com/coder/coder/v2/codersdk" "cdr.dev/slog" - "github.com/coder/coder/v2/coderd/database" - "github.com/coder/coder/v2/coderd/database/dbauthz" "github.com/google/uuid" "golang.org/x/sync/errgroup" "golang.org/x/xerrors" + + "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/database/dbauthz" ) type Controller struct { @@ -395,13 +399,26 @@ func (c Controller) deletePrebuild(ctx context.Context, db database.Store, prebu } func (c Controller) provision(ctx context.Context, db database.Store, prebuildID uuid.UUID, template database.Template, transition database.WorkspaceTransition, workspace database.Workspace) error { + tvp, err := db.GetPresetParametersByTemplateVersionID(ctx, template.ActiveVersionID) + if err != nil { + return xerrors.Errorf("fetch preset details: %w", err) + } + + var params []codersdk.WorkspaceBuildParameter + for _, param := range tvp { + params = append(params, codersdk.WorkspaceBuildParameter{ + Name: param.Name, + Value: param.Value, + }) + } + builder := wsbuilder.New(workspace, transition). Reason(database.BuildReasonInitiator). Initiator(PrebuildOwnerUUID). ActiveVersion(). VersionID(template.ActiveVersionID). - MarkPrebuild() - // RichParameterValues(req.RichParameterValues) // TODO: fetch preset's params + MarkPrebuild(). + RichParameterValues(params) _, provisionerJob, _, err := builder.Build( ctx, diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index a8203ecb4d..abbed205bb 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -1713,13 +1713,13 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) // If this job was initiated by the prebuilds user and the job is not a prebuild, then it MUST be the claim run. // TODO: maybe add some specific metadata to indicate this rather than imputing it. - if input.PrebuildClaimByUser != uuid.Nil { + if input.PrebuildClaimedByUser != uuid.Nil { channel := agentsdk.PrebuildClaimedChannel(workspace.ID) s.Logger.Info(ctx, "workspace prebuild successfully claimed by user", - slog.F("user", input.PrebuildClaimByUser.String()), + slog.F("user", input.PrebuildClaimedByUser.String()), slog.F("workspace_id", workspace.ID), slog.F("channel", channel)) - if err := s.Pubsub.Publish(channel, []byte(input.PrebuildClaimByUser.String())); err != nil { + if err := s.Pubsub.Publish(channel, []byte(input.PrebuildClaimedByUser.String())); err != nil { s.Logger.Error(ctx, "failed to publish message to workspace agent to pull new manifest", slog.Error(err)) } } @@ -1881,22 +1881,23 @@ func InsertWorkspacePresetAndParameters(ctx context.Context, db database.Store, if err != nil { return xerrors.Errorf("insert preset parameters: %w", err) } + + if protoPreset.Prebuild != nil { + _, err := db.InsertPresetPrebuild(ctx, database.InsertPresetPrebuildParams{ + ID: uuid.New(), + PresetID: dbPreset.ID, + DesiredInstances: protoPreset.Prebuild.Instances, + InvalidateAfterSecs: 0, // TODO: implement cache invalidation + }) + if err != nil { + return xerrors.Errorf("insert preset prebuild: %w", err) + } + } return nil }, nil) if err != nil { return xerrors.Errorf("insert preset and parameters: %w", err) } - if protoPreset.Prebuild != nil { - _, err := db.InsertPresetPrebuild(ctx, database.InsertPresetPrebuildParams{ - ID: uuid.New(), - PresetID: dbPreset.ID, - DesiredInstances: protoPreset.Prebuild.Instances, - InvalidateAfterSecs: 0, // TODO: implement cache invalidation - }) - if err != nil { - return xerrors.Errorf("insert preset prebuild: %w", err) - } - } return nil } @@ -2383,10 +2384,10 @@ type TemplateVersionImportJob struct { // WorkspaceProvisionJob is the payload for the "workspace_provision" job type. type WorkspaceProvisionJob struct { - WorkspaceBuildID uuid.UUID `json:"workspace_build_id"` - DryRun bool `json:"dry_run"` - IsPrebuild bool `json:"is_prebuild,omitempty"` - PrebuildClaimByUser uuid.UUID `json:"prebuild_claim_by,omitempty"` + WorkspaceBuildID uuid.UUID `json:"workspace_build_id"` + DryRun bool `json:"dry_run"` + IsPrebuild bool `json:"is_prebuild,omitempty"` + PrebuildClaimedByUser uuid.UUID `json:"prebuild_claimed_by,omitempty"` // RunningWorkspaceAgentID is *only* used for prebuilds. We pass it down when we want to rebuild a prebuilt workspace // but not generate a new agent token. The provisionerdserver will retrieve this token and push it down to // the provisioner (and ultimately to the `coder_agent` resource in the Terraform provider) where it will be diff --git a/coderd/workspaces.go b/coderd/workspaces.go index c0455925b1..268d620fd6 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -6,18 +6,20 @@ import ( "encoding/json" "errors" "fmt" - "github.com/coder/coder/v2/coderd/prebuilds" "net/http" "slices" "strconv" "time" + "github.com/coder/coder/v2/coderd/prebuilds" + "github.com/dustin/go-humanize" "github.com/go-chi/chi/v5" "github.com/google/uuid" "golang.org/x/xerrors" "cdr.dev/slog" + "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/database" @@ -729,7 +731,7 @@ func createWorkspace( } if claimedWorkspace != nil { - builder = builder.MarkPrebuildClaimBy(owner.ID) + builder = builder.MarkPrebuildClaimedBy(owner.ID) } workspaceBuild, provisionerJob, provisionerDaemons, err = builder.Build( diff --git a/coderd/wsbuilder/wsbuilder.go b/coderd/wsbuilder/wsbuilder.go index 9671f2cbed..5af38d1c23 100644 --- a/coderd/wsbuilder/wsbuilder.go +++ b/coderd/wsbuilder/wsbuilder.go @@ -74,7 +74,7 @@ type Builder struct { parameterValues *[]string prebuild bool - prebuildClaimBy uuid.UUID + prebuildClaimedBy uuid.UUID runningWorkspaceAgentID uuid.UUID verifyNoLegacyParametersOnce bool @@ -178,9 +178,9 @@ func (b Builder) MarkPrebuild() Builder { return b } -func (b Builder) MarkPrebuildClaimBy(userID uuid.UUID) Builder { +func (b Builder) MarkPrebuildClaimedBy(userID uuid.UUID) Builder { // nolint: revive - b.prebuildClaimBy = userID + b.prebuildClaimedBy = userID return b } @@ -319,7 +319,7 @@ func (b *Builder) buildTx(authFunc func(action policy.Action, object rbac.Object WorkspaceBuildID: workspaceBuildID, LogLevel: b.logLevel, IsPrebuild: b.prebuild, - PrebuildClaimByUser: b.prebuildClaimBy, + PrebuildClaimedByUser: b.prebuildClaimedBy, RunningWorkspaceAgentID: b.runningWorkspaceAgentID, }) if err != nil { @@ -613,6 +613,11 @@ func (b *Builder) findNewBuildParameterValue(name string) *codersdk.WorkspaceBui } func (b *Builder) getLastBuildParameters() ([]database.WorkspaceBuildParameter, error) { + // TODO: exclude preset params from this list instead of returning nothing? + if b.prebuildClaimedBy != uuid.Nil { + return nil, nil + } + if b.lastBuildParameters != nil { return *b.lastBuildParameters, nil }