Serve starts a dRPC server on the provided transport speaking Terraform provisioner.
(ctx context.Context, options *ServeOptions)
| 86 | |
| 87 | // Serve starts a dRPC server on the provided transport speaking Terraform provisioner. |
| 88 | func Serve(ctx context.Context, options *ServeOptions) error { |
| 89 | if options.BinaryPath == "" { |
| 90 | binaryDetails, err := systemBinary(ctx) |
| 91 | if err != nil { |
| 92 | // This is an early exit to prevent extra execution in case the context is canceled. |
| 93 | // It generally happens in unit tests since this method is asynchronous and |
| 94 | // the unit test kills the app before this is complete. |
| 95 | if errors.Is(err, context.Canceled) { |
| 96 | return xerrors.Errorf("system binary context canceled: %w", err) |
| 97 | } |
| 98 | |
| 99 | if errors.Is(err, errTerraformMinorVersionMismatch) { |
| 100 | options.Logger.Warn(ctx, "installed terraform version too old, will download known good version to cache, or use a previously cached version", |
| 101 | slog.F("installed_version", binaryDetails.version.String()), |
| 102 | slog.F("min_version", minTerraformVersion.String())) |
| 103 | } |
| 104 | |
| 105 | binPath, err := Install(ctx, options.Logger, options.ExternalProvisioner, options.CachePath, TerraformVersion, "") |
| 106 | if err != nil { |
| 107 | return xerrors.Errorf("install terraform: %w", err) |
| 108 | } |
| 109 | options.BinaryPath = binPath |
| 110 | } else { |
| 111 | logVersion := options.Logger.Debug |
| 112 | if options.ExternalProvisioner { |
| 113 | logVersion = options.Logger.Info |
| 114 | } |
| 115 | logVersion(ctx, "detected terraform version", |
| 116 | slog.F("installed_version", binaryDetails.version.String()), |
| 117 | slog.F("min_version", minTerraformVersion.String()), |
| 118 | slog.F("max_version", maxTerraformVersion.String())) |
| 119 | // Warn if the installed version is newer than what we've decided is the max. |
| 120 | // We used to ignore it and download our own version but this makes it easier |
| 121 | // to test out newer versions of Terraform. |
| 122 | if binaryDetails.version.GreaterThanOrEqual(maxTerraformVersion) { |
| 123 | options.Logger.Warn(ctx, "installed terraform version newer than expected, you may experience bugs", |
| 124 | slog.F("installed_version", binaryDetails.version.String()), |
| 125 | slog.F("max_version", maxTerraformVersion.String())) |
| 126 | } |
| 127 | options.BinaryPath = binaryDetails.absolutePath |
| 128 | } |
| 129 | } |
| 130 | if options.Tracer == nil { |
| 131 | options.Tracer = trace.NewNoopTracerProvider().Tracer("noop") |
| 132 | } |
| 133 | if options.ExitTimeout == 0 { |
| 134 | options.ExitTimeout = jobreaper.HungJobExitTimeout |
| 135 | } |
| 136 | return provisionersdk.Serve(ctx, &server{ |
| 137 | execMut: &sync.Mutex{}, |
| 138 | binaryPath: options.BinaryPath, |
| 139 | cachePath: options.CachePath, |
| 140 | cliConfigPath: options.CliConfigPath, |
| 141 | logger: options.Logger, |
| 142 | tracer: options.Tracer, |
| 143 | exitTimeout: options.ExitTimeout, |
| 144 | }, options.ServeOptions) |
| 145 | } |