@@ -283,7 +283,7 @@ func (e *executor) init(ctx, killCtx context.Context, logr logSink) error {
283283func checksumFileCRC32 (ctx context.Context , logger slog.Logger , path string ) uint32 {
284284 content , err := os .ReadFile (path )
285285 if err != nil {
286- logger .Debug (ctx , "file %s does not exist or can't be read, skip checksum calculation" )
286+ logger .Debug (ctx , fmt . Sprintf ( "file %s does not exist or can't be read, skip checksum calculation" , path ) )
287287 return 0
288288 }
289289 return crc32 .ChecksumIEEE (content )
@@ -332,34 +332,16 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
332332 return nil , xerrors .Errorf ("terraform plan: %w" , err )
333333 }
334334
335- // Capture the duration of the call to `terraform graph`.
336- graphTimings := newTimingAggregator (database .ProvisionerJobTimingStageGraph )
337- graphTimings .ingest (createGraphTimingsEvent (timingGraphStart ))
338-
339- state , plan , err := e .planResources (ctx , killCtx , planfilePath )
335+ plan , err := e .parsePlan (ctx , killCtx , planfilePath )
340336 if err != nil {
341- graphTimings .ingest (createGraphTimingsEvent (timingGraphErrored ))
342- return nil , xerrors .Errorf ("plan resources: %w" , err )
337+ return nil , xerrors .Errorf ("show terraform plan file: %w" , err )
343338 }
339+
344340 planJSON , err := json .Marshal (plan )
345341 if err != nil {
346342 return nil , xerrors .Errorf ("marshal plan: %w" , err )
347343 }
348344
349- graphTimings .ingest (createGraphTimingsEvent (timingGraphComplete ))
350-
351- var moduleFiles []byte
352- // Skipping modules archiving is useful if the caller does not need it, eg during
353- // a workspace build. This removes some added costs of sending the modules
354- // payload back to coderd if coderd is just going to ignore it.
355- if ! req .OmitModuleFiles {
356- moduleFiles , err = GetModulesArchive (os .DirFS (e .files .WorkDirectory ()))
357- if err != nil {
358- // TODO: we probably want to persist this error or make it louder eventually
359- e .logger .Warn (ctx , "failed to archive terraform modules" , slog .Error (err ))
360- }
361- }
362-
363345 // When a prebuild claim attempt is made, log a warning if a resource is due to be replaced, since this will obviate
364346 // the point of prebuilding if the expensive resource is replaced once claimed!
365347 var (
@@ -386,20 +368,19 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
386368 }
387369 }
388370
371+ state , err := ConvertPlanState (plan )
372+ if err != nil {
373+ return nil , xerrors .Errorf ("convert plan state: %w" , err )
374+ }
375+
389376 // DoneOut must be completed before we aggregate timings to ensure all logs have been processed.
390377 <- doneOut
391378 msg := & proto.PlanComplete {
392- Parameters : state .Parameters ,
393- Resources : state .Resources ,
394- ExternalAuthProviders : state .ExternalAuthProviders ,
395- Timings : append (e .timings .aggregate (), graphTimings .aggregate ()... ),
396- Presets : state .Presets ,
397- Plan : planJSON ,
398- ResourceReplacements : resReps ,
399- ModuleFiles : moduleFiles ,
400- HasAiTasks : state .HasAITasks ,
401- AiTasks : state .AITasks ,
402- HasExternalAgents : state .HasExternalAgents ,
379+ Timings : e .timings .aggregate (),
380+ Plan : planJSON ,
381+ DailyCost : state .DailyCost ,
382+ ResourceReplacements : resReps ,
383+ AiTaskCount : state .AITaskCount ,
403384 }
404385
405386 return msg , nil
@@ -422,42 +403,6 @@ func onlyDataResources(sm tfjson.StateModule) tfjson.StateModule {
422403 return filtered
423404}
424405
425- // planResources must only be called while the lock is held.
426- func (e * executor ) planResources (ctx , killCtx context.Context , planfilePath string ) (* State , * tfjson.Plan , error ) {
427- ctx , span := e .server .startTrace (ctx , tracing .FuncName ())
428- defer span .End ()
429-
430- plan , err := e .parsePlan (ctx , killCtx , planfilePath )
431- if err != nil {
432- return nil , nil , xerrors .Errorf ("show terraform plan file: %w" , err )
433- }
434-
435- rawGraph , err := e .graph (ctx , killCtx )
436- if err != nil {
437- return nil , nil , xerrors .Errorf ("graph: %w" , err )
438- }
439- modules := []* tfjson.StateModule {}
440- if plan .PriorState != nil {
441- // We need the data resources for rich parameters. For some reason, they
442- // only show up in the PriorState.
443- //
444- // We don't want all prior resources, because Quotas (and
445- // future features) would never know which resources are getting
446- // deleted by a stop.
447-
448- filtered := onlyDataResources (* plan .PriorState .Values .RootModule )
449- modules = append (modules , & filtered )
450- }
451- modules = append (modules , plan .PlannedValues .RootModule )
452-
453- state , err := ConvertState (ctx , modules , rawGraph , e .server .logger )
454- if err != nil {
455- return nil , nil , err
456- }
457-
458- return state , plan , nil
459- }
460-
461406// parsePlan must only be called while the lock is held.
462407func (e * executor ) parsePlan (ctx , killCtx context.Context , planfilePath string ) (* tfjson.Plan , error ) {
463408 ctx , span := e .server .startTrace (ctx , tracing .FuncName ())
@@ -545,9 +490,11 @@ func (e *executor) graph(ctx, killCtx context.Context) (string, error) {
545490 // TODO: When the plan is present, we should probably use it?
546491 // "-plan=" + e.files.PlanFilePath(),
547492 }
493+
548494 if ver .GreaterThanOrEqual (version170 ) {
549495 args = append (args , "-type=plan" )
550496 }
497+
551498 var out strings.Builder
552499 cmd := exec .CommandContext (killCtx , e .binaryPath , args ... ) // #nosec
553500 cmd .Stdout = & out
@@ -608,11 +555,6 @@ func (e *executor) apply(
608555 return nil , xerrors .Errorf ("terraform apply: %w" , err )
609556 }
610557
611- // `terraform show` & `terraform graph`
612- state , err := e .stateResources (ctx , killCtx )
613- if err != nil {
614- return nil , err
615- }
616558 statefilePath := e .files .StateFilePath ()
617559 stateContent , err := os .ReadFile (statefilePath )
618560 if err != nil {
@@ -623,42 +565,11 @@ func (e *executor) apply(
623565 <- doneOut
624566 agg := e .timings .aggregate ()
625567 return & proto.ApplyComplete {
626- Parameters : state .Parameters ,
627- Resources : state .Resources ,
628- ExternalAuthProviders : state .ExternalAuthProviders ,
629- State : stateContent ,
630- Timings : agg ,
631- AiTasks : state .AITasks ,
568+ State : stateContent ,
569+ Timings : agg ,
632570 }, nil
633571}
634572
635- // stateResources must only be called while the lock is held.
636- func (e * executor ) stateResources (ctx , killCtx context.Context ) (* State , error ) {
637- ctx , span := e .server .startTrace (ctx , tracing .FuncName ())
638- defer span .End ()
639-
640- state , err := e .state (ctx , killCtx )
641- if err != nil {
642- return nil , err
643- }
644- rawGraph , err := e .graph (ctx , killCtx )
645- if err != nil {
646- return nil , xerrors .Errorf ("get terraform graph: %w" , err )
647- }
648- converted := & State {}
649- if state .Values == nil {
650- return converted , nil
651- }
652-
653- converted , err = ConvertState (ctx , []* tfjson.StateModule {
654- state .Values .RootModule ,
655- }, rawGraph , e .server .logger )
656- if err != nil {
657- return nil , err
658- }
659- return converted , nil
660- }
661-
662573// state must only be called while the lock is held.
663574func (e * executor ) state (ctx , killCtx context.Context ) (* tfjson.State , error ) {
664575 ctx , span := e .server .startTrace (ctx , tracing .FuncName ())
0 commit comments