mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-19 17:59:05 -05:00
To facilitate early development and testing of the new language runtime we're introducing a temporary mechanism to opt in to using the new codepaths based on an environment variable. This environment variable is effective only for experiment-enabled builds of OpenTofu, and so it will be completely ignored by official releases of OpenTofu. This commit just deals with the "wiring" of this new mechanism, without actually connecting it with the new language runtime yet. The goal here is to disturb existing codepaths as little as possible to minimize both the risk of making this change and the burden this causes for ongoing maintenance unrelated to work on the new language runtime. This strategy of switching at the local backend layer means that we will have some duplicated logic in the experimental functions compared to the non-experimental functions, which is an intentional tradeoff to allow us to isolate what we're doing so we don't churn existing code while we're still in this early exploration phase. In a later phase of the language runtime project we may pivot to a different approach which switches at a deeper point in the call stack, but for now we're keeping this broad to give us flexibility. Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
100 lines
4.0 KiB
Go
100 lines
4.0 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package local
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"os"
|
|
"sync/atomic"
|
|
|
|
"github.com/opentofu/opentofu/internal/backend"
|
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
|
)
|
|
|
|
/////////////////////////
|
|
// The definitions in this file are intended as temporary shims to help support
|
|
// the development of the new runtime engine, by allowing experiments-enabled
|
|
// builds to be opted in to the new implementation by setting the environment
|
|
// variable TOFU_X_EXPERIMENTAL_RUNTIME to any non-empty value.
|
|
//
|
|
// These shims should remain here only as long as the new runtime engine is
|
|
// under active development and is not yet adopted as the primary engine. It's
|
|
// also acceptable for work being done for other separate projects to ignore
|
|
// these shims and let this code become broken, as long as the code continues
|
|
// to compile: only those working on the implementation of the new engine are
|
|
// responsible for updating this if the rest of the system evolves to the point
|
|
// of that being necessary.
|
|
//
|
|
// Note that "tofu validate" is implemented outside of the backend abstraction
|
|
// and so does not respond to the experiment opt-in environment variable. For
|
|
// now, try out validation-related behaviors of the new runtime through
|
|
// "tofu plan" instead, which should implement a superset of the validation
|
|
// behavior.
|
|
/////////////////////////
|
|
|
|
// SetExperimentalRuntimeAllowed must be called with the argument set to true
|
|
// at some point before calling [New] or [NewWithBackend] in order for the
|
|
// experimental opt-in to be effective.
|
|
//
|
|
// In practice this is called by code in the "command" package early in the
|
|
// backend initialization codepath and enables the experimental runtime only
|
|
// in an experiments-enabled OpenTofu build, to make sure that it's not
|
|
// possible to accidentally enable this experimental functionality in normal
|
|
// release builds.
|
|
//
|
|
// Refer to "cmd/tofu/experiments.go" for information on how to produce an
|
|
// experiments-enabled build.
|
|
func SetExperimentalRuntimeAllowed(allowed bool) {
|
|
experimentalRuntimeAllowed.Store(allowed)
|
|
}
|
|
|
|
var experimentalRuntimeAllowed atomic.Bool
|
|
|
|
func experimentalRuntimeEnabled() bool {
|
|
if !experimentalRuntimeAllowed.Load() {
|
|
// The experimental runtime is never enabled when it hasn't been
|
|
// explicitly allowed.
|
|
return false
|
|
}
|
|
|
|
optIn := os.Getenv("TOFU_X_EXPERIMENTAL_RUNTIME")
|
|
return optIn != ""
|
|
}
|
|
|
|
func (b *Local) opPlanWithExperimentalRuntime(stopCtx context.Context, cancelCtx context.Context, op *backend.Operation, runningOp *backend.RunningOperation) {
|
|
log.Println("[WARN] Using plan implementation from the experimental language runtime")
|
|
var diags tfdiags.Diagnostics
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"Operation unsupported in experimental language runtime",
|
|
"The command \"tofu plan\" is not yet supported under the experimental language runtime.",
|
|
))
|
|
op.ReportResult(runningOp, diags)
|
|
}
|
|
|
|
func (b *Local) opApplyWithExperimentalRuntime(stopCtx context.Context, cancelCtx context.Context, op *backend.Operation, runningOp *backend.RunningOperation) {
|
|
log.Println("[WARN] Using apply implementation from the experimental language runtime")
|
|
var diags tfdiags.Diagnostics
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"Operation unsupported in experimental language runtime",
|
|
"The command \"tofu apply\" is not yet supported under the experimental language runtime.",
|
|
))
|
|
op.ReportResult(runningOp, diags)
|
|
}
|
|
|
|
func (b *Local) opRefreshWithExperimentalRuntime(stopCtx context.Context, cancelCtx context.Context, op *backend.Operation, runningOp *backend.RunningOperation) {
|
|
log.Println("[WARN] Using refresh implementation from the experimental language runtime")
|
|
var diags tfdiags.Diagnostics
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"Operation unsupported in experimental language runtime",
|
|
"The command \"tofu refresh\" is not yet supported under the experimental language runtime.",
|
|
))
|
|
op.ReportResult(runningOp, diags)
|
|
}
|