MCPcopy Index your code
hub / github.com/coder/coder / Apply

Method Apply

provisioner/terraform/provision.go:284–337  ·  view source on GitHub ↗
(
	sess *provisionersdk.Session, request *proto.ApplyRequest, canceledOrComplete <-chan struct{},
)

Source from the content-addressed store, hash-verified

282}
283
284func (s *server) Apply(
285 sess *provisionersdk.Session, request *proto.ApplyRequest, canceledOrComplete <-chan struct{},
286) *proto.ApplyComplete {
287 ctx, span := s.startTrace(sess.Context(), tracing.FuncName())
288 defer span.End()
289 ctx, cancel, killCtx, kill := s.setupContexts(ctx, canceledOrComplete)
290 defer cancel()
291 defer kill()
292
293 e := s.executor(sess.Files, database.ProvisionerJobTimingStageApply)
294 if err := e.checkMinVersion(ctx); err != nil {
295 return provisionersdk.ApplyErrorf("%s", err.Error())
296 }
297 logTerraformEnvVars(sess)
298
299 // Earlier in the session, Plan() will have written the state file and the plan file.
300 statefilePath := sess.Files.StateFilePath()
301
302 // Exit early if there is no state file. This is necessary to
303 // avoid any cases where a workspace is "locked out" of terraform due to
304 // e.g. bad template param values and cannot be deleted. This is just for
305 // contingency, in the future we will try harder to prevent workspaces being
306 // broken this hard.
307 if request.Metadata.GetWorkspaceTransition() == proto.WorkspaceTransition_DESTROY {
308 if _, err := os.Stat(statefilePath); errors.Is(err, os.ErrNotExist) {
309 sess.ProvisionLog(proto.LogLevel_INFO, "The terraform state does not exist, there is nothing to do")
310 return &proto.ApplyComplete{}
311 }
312 }
313
314 env, err := provisionEnv(sess.Config, request.Metadata, nil, nil, nil)
315 if err != nil {
316 return provisionersdk.ApplyErrorf("provision env: %s", err)
317 }
318 env = otelEnvInject(ctx, env)
319 endStage := e.timings.startStage(database.ProvisionerJobTimingStageApply)
320 resp, err := e.apply(
321 ctx, killCtx, env, sess,
322 )
323 endStage(err)
324 if err != nil {
325 errorMessage := err.Error()
326 // Terraform can fail and apply and still need to store it's state.
327 // In this case, we return Complete with an explicit error message.
328 stateData, _ := os.ReadFile(statefilePath)
329 return &proto.ApplyComplete{
330 State: stateData,
331 Error: errorMessage,
332 Timings: e.timings.aggregate(),
333 }
334 }
335 resp.Timings = e.timings.aggregate()
336 return resp
337}
338
339func planVars(plan *proto.PlanRequest) ([]string, error) {
340 vars := []string{}

Callers

nothing calls this directly

Calls 15

startTraceMethod · 0.95
setupContextsMethod · 0.95
executorMethod · 0.95
FuncNameFunction · 0.92
ApplyErrorfFunction · 0.92
logTerraformEnvVarsFunction · 0.85
provisionEnvFunction · 0.85
otelEnvInjectFunction · 0.85
checkMinVersionMethod · 0.80
StateFilePathMethod · 0.80
startStageMethod · 0.80

Tested by

no test coverage detected