@@ -23,7 +23,6 @@ import (
2323 "cdr.dev/slog"
2424 "github.com/coder/coder/v2/provisionersdk/tfpath"
2525
26- "github.com/coder/coder/v2/coderd/database"
2726 "github.com/coder/coder/v2/coderd/tracing"
2827 "github.com/coder/coder/v2/provisionersdk/proto"
2928)
@@ -283,7 +282,7 @@ func (e *executor) init(ctx, killCtx context.Context, logr logSink) error {
283282func checksumFileCRC32 (ctx context.Context , logger slog.Logger , path string ) uint32 {
284283 content , err := os .ReadFile (path )
285284 if err != nil {
286- logger .Debug (ctx , "file %s does not exist or can't be read, skip checksum calculation" )
285+ logger .Debug (ctx , fmt . Sprintf ( "file %s does not exist or can't be read, skip checksum calculation" , path ) )
287286 return 0
288287 }
289288 return crc32 .ChecksumIEEE (content )
@@ -330,34 +329,16 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
330329 return nil , xerrors .Errorf ("terraform plan: %w" , err )
331330 }
332331
333- // Capture the duration of the call to `terraform graph`.
334- graphTimings := newTimingAggregator (database .ProvisionerJobTimingStageGraph )
335- graphTimings .ingest (createGraphTimingsEvent (timingGraphStart ))
336-
337- state , plan , err := e .planResources (ctx , killCtx , planfilePath )
332+ plan , err := e .parsePlan (ctx , killCtx , planfilePath )
338333 if err != nil {
339- graphTimings .ingest (createGraphTimingsEvent (timingGraphErrored ))
340- return nil , xerrors .Errorf ("plan resources: %w" , err )
334+ return nil , xerrors .Errorf ("show terraform plan file: %w" , err )
341335 }
336+
342337 planJSON , err := json .Marshal (plan )
343338 if err != nil {
344339 return nil , xerrors .Errorf ("marshal plan: %w" , err )
345340 }
346341
347- graphTimings .ingest (createGraphTimingsEvent (timingGraphComplete ))
348-
349- var moduleFiles []byte
350- // Skipping modules archiving is useful if the caller does not need it, eg during
351- // a workspace build. This removes some added costs of sending the modules
352- // payload back to coderd if coderd is just going to ignore it.
353- if ! req .OmitModuleFiles {
354- moduleFiles , err = GetModulesArchive (os .DirFS (e .files .WorkDirectory ()))
355- if err != nil {
356- // TODO: we probably want to persist this error or make it louder eventually
357- e .logger .Warn (ctx , "failed to archive terraform modules" , slog .Error (err ))
358- }
359- }
360-
361342 // When a prebuild claim attempt is made, log a warning if a resource is due to be replaced, since this will obviate
362343 // the point of prebuilding if the expensive resource is replaced once claimed!
363344 var (
@@ -384,18 +365,16 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
384365 }
385366 }
386367
368+ state , err := ConvertPlanState (plan )
369+ if err != nil {
370+ return nil , xerrors .Errorf ("convert plan state: %w" , err )
371+ }
372+
387373 msg := & proto.PlanComplete {
388- Parameters : state .Parameters ,
389- Resources : state .Resources ,
390- ExternalAuthProviders : state .ExternalAuthProviders ,
391- Timings : graphTimings .aggregate (),
392- Presets : state .Presets ,
393- Plan : planJSON ,
394- ResourceReplacements : resReps ,
395- ModuleFiles : moduleFiles ,
396- HasAiTasks : state .HasAITasks ,
397- AiTasks : state .AITasks ,
398- HasExternalAgents : state .HasExternalAgents ,
374+ Plan : planJSON ,
375+ DailyCost : state .DailyCost ,
376+ ResourceReplacements : resReps ,
377+ AiTaskCount : state .AITaskCount ,
399378 }
400379
401380 return msg , nil
@@ -418,42 +397,6 @@ func onlyDataResources(sm tfjson.StateModule) tfjson.StateModule {
418397 return filtered
419398}
420399
421- // planResources must only be called while the lock is held.
422- func (e * executor ) planResources (ctx , killCtx context.Context , planfilePath string ) (* State , * tfjson.Plan , error ) {
423- ctx , span := e .server .startTrace (ctx , tracing .FuncName ())
424- defer span .End ()
425-
426- plan , err := e .parsePlan (ctx , killCtx , planfilePath )
427- if err != nil {
428- return nil , nil , xerrors .Errorf ("show terraform plan file: %w" , err )
429- }
430-
431- rawGraph , err := e .graph (ctx , killCtx )
432- if err != nil {
433- return nil , nil , xerrors .Errorf ("graph: %w" , err )
434- }
435- modules := []* tfjson.StateModule {}
436- if plan .PriorState != nil {
437- // We need the data resources for rich parameters. For some reason, they
438- // only show up in the PriorState.
439- //
440- // We don't want all prior resources, because Quotas (and
441- // future features) would never know which resources are getting
442- // deleted by a stop.
443-
444- filtered := onlyDataResources (* plan .PriorState .Values .RootModule )
445- modules = append (modules , & filtered )
446- }
447- modules = append (modules , plan .PlannedValues .RootModule )
448-
449- state , err := ConvertState (ctx , modules , rawGraph , e .server .logger )
450- if err != nil {
451- return nil , nil , err
452- }
453-
454- return state , plan , nil
455- }
456-
457400// parsePlan must only be called while the lock is held.
458401func (e * executor ) parsePlan (ctx , killCtx context.Context , planfilePath string ) (* tfjson.Plan , error ) {
459402 ctx , span := e .server .startTrace (ctx , tracing .FuncName ())
@@ -541,9 +484,11 @@ func (e *executor) graph(ctx, killCtx context.Context) (string, error) {
541484 // TODO: When the plan is present, we should probably use it?
542485 // "-plan=" + e.files.PlanFilePath(),
543486 }
487+
544488 if ver .GreaterThanOrEqual (version170 ) {
545489 args = append (args , "-type=plan" )
546490 }
491+
547492 var out strings.Builder
548493 cmd := exec .CommandContext (killCtx , e .binaryPath , args ... ) // #nosec
549494 cmd .Stdout = & out
@@ -602,53 +547,17 @@ func (e *executor) apply(
602547 return nil , xerrors .Errorf ("terraform apply: %w" , err )
603548 }
604549
605- // `terraform show` & `terraform graph`
606- state , err := e .stateResources (ctx , killCtx )
607- if err != nil {
608- return nil , err
609- }
610550 statefilePath := e .files .StateFilePath ()
611551 stateContent , err := os .ReadFile (statefilePath )
612552 if err != nil {
613553 return nil , xerrors .Errorf ("read statefile %q: %w" , statefilePath , err )
614554 }
615555
616556 return & proto.ApplyComplete {
617- Parameters : state .Parameters ,
618- Resources : state .Resources ,
619- ExternalAuthProviders : state .ExternalAuthProviders ,
620- State : stateContent ,
621- AiTasks : state .AITasks ,
557+ State : stateContent ,
622558 }, nil
623559}
624560
625- // stateResources must only be called while the lock is held.
626- func (e * executor ) stateResources (ctx , killCtx context.Context ) (* State , error ) {
627- ctx , span := e .server .startTrace (ctx , tracing .FuncName ())
628- defer span .End ()
629-
630- state , err := e .state (ctx , killCtx )
631- if err != nil {
632- return nil , err
633- }
634- rawGraph , err := e .graph (ctx , killCtx )
635- if err != nil {
636- return nil , xerrors .Errorf ("get terraform graph: %w" , err )
637- }
638- converted := & State {}
639- if state .Values == nil {
640- return converted , nil
641- }
642-
643- converted , err = ConvertState (ctx , []* tfjson.StateModule {
644- state .Values .RootModule ,
645- }, rawGraph , e .server .logger )
646- if err != nil {
647- return nil , err
648- }
649- return converted , nil
650- }
651-
652561// state must only be called while the lock is held.
653562func (e * executor ) state (ctx , killCtx context.Context ) (* tfjson.State , error ) {
654563 ctx , span := e .server .startTrace (ctx , tracing .FuncName ())
0 commit comments