blob: cc40666ba13ca8010212e1050b68fbe135c93cf1 [file]
// Copyright IBM Corp. 2020, 2026
// SPDX-License-Identifier: MPL-2.0
package tfexec
import (
"context"
"fmt"
"iter"
"os/exec"
)
type stateMigrateConfig struct {
srcProviderLockFile string
dstProviderLockFile string
upgrade bool
reattachInfo ReattachInfo
}
var defaultStateMigrateOptions = stateMigrateConfig{}
// StateMigrateOption represents options used in the StateMigrate method.
type StateMigrateOption interface {
configureStateMigrate(*stateMigrateConfig)
}
func (opt *SourceProviderLockFileOption) configureStateMigrate(conf *stateMigrateConfig) {
conf.srcProviderLockFile = opt.path
}
func (opt *DestinationProviderLockFileOption) configureStateMigrate(conf *stateMigrateConfig) {
conf.dstProviderLockFile = opt.path
}
func (opt *UpgradeOption) configureStateMigrate(conf *stateMigrateConfig) {
conf.upgrade = opt.upgrade
}
func (opt *ReattachOption) configureStateMigrate(conf *stateMigrateConfig) {
conf.reattachInfo = opt.info
}
// StateMigrateJSON executes `terraform state migrate` with `-json` flag
// and any specified options and waits for it to complete.
//
// StateMigrateJSON is likely to be removed in a future major version in favour of
// StateMigrate returning JSON by default.
func (tf *Terraform) StateMigrateJSON(ctx context.Context, opts ...StateMigrateOption) (iter.Seq[NextMessage], error) {
err := tf.compatible(ctx, tf1_18_0, nil)
if err != nil {
return nil, fmt.Errorf("terraform state migrate -json was added in 1.18.0: %w", err)
}
cmd, err := tf.stateMigrateJSONCmd(ctx, opts...)
if err != nil {
return nil, err
}
return tf.runTerraformCmdJSONLog(ctx, cmd), nil
}
func (tf *Terraform) stateMigrateJSONCmd(ctx context.Context, opts ...StateMigrateOption) (*exec.Cmd, error) {
c := defaultStateMigrateOptions
for _, o := range opts {
o.configureStateMigrate(&c)
}
mergeEnv := map[string]string{}
if c.reattachInfo != nil {
reattachStr, err := c.reattachInfo.marshalString()
if err != nil {
return nil, err
}
mergeEnv[reattachEnvVar] = reattachStr
}
args := tf.buildStateMigrateArgs(c)
return tf.buildTerraformCmd(ctx, mergeEnv, args...), nil
}
func (tf *Terraform) buildStateMigrateArgs(c stateMigrateConfig) []string {
args := []string{
"state", "migrate",
"-no-color",
"-input=false",
"-force-copy",
"-json",
}
if c.srcProviderLockFile != "" {
args = append(args, "-source-provider-lock-file="+c.srcProviderLockFile)
}
if c.dstProviderLockFile != "" {
args = append(args, "-destination-provider-lock-file="+c.dstProviderLockFile)
}
if c.upgrade {
args = append(args, "-upgrade")
}
return args
}