github.com/databricks/cli@v0.203.0/bundle/deploy/terraform/state_pull.go (about) 1 package terraform 2 3 import ( 4 "context" 5 "errors" 6 "io" 7 "io/fs" 8 "os" 9 "path/filepath" 10 11 "github.com/databricks/cli/bundle" 12 "github.com/databricks/cli/libs/filer" 13 "github.com/databricks/cli/libs/log" 14 ) 15 16 type statePull struct{} 17 18 func (l *statePull) Name() string { 19 return "terraform:state-pull" 20 } 21 22 func (l *statePull) Apply(ctx context.Context, b *bundle.Bundle) error { 23 f, err := filer.NewWorkspaceFilesClient(b.WorkspaceClient(), b.Config.Workspace.StatePath) 24 if err != nil { 25 return err 26 } 27 28 dir, err := Dir(b) 29 if err != nil { 30 return err 31 } 32 33 // Download state file from filer to local cache directory. 34 log.Infof(ctx, "Opening remote state file") 35 remote, err := f.Read(ctx, TerraformStateFileName) 36 if err != nil { 37 // On first deploy this state file doesn't yet exist. 38 if errors.Is(err, fs.ErrNotExist) { 39 log.Infof(ctx, "Remote state file does not exist") 40 return nil 41 } 42 return err 43 } 44 45 // Expect the state file to live under dir. 46 local, err := os.OpenFile(filepath.Join(dir, TerraformStateFileName), os.O_CREATE|os.O_RDWR, 0600) 47 if err != nil { 48 return err 49 } 50 defer local.Close() 51 52 if !IsLocalStateStale(local, remote) { 53 log.Infof(ctx, "Local state is the same or newer, ignoring remote state") 54 return nil 55 } 56 57 // Truncating the file before writing 58 local.Truncate(0) 59 local.Seek(0, 0) 60 61 // Write file to disk. 62 log.Infof(ctx, "Writing remote state file to local cache directory") 63 _, err = io.Copy(local, remote) 64 if err != nil { 65 return err 66 } 67 68 return nil 69 } 70 71 func StatePull() bundle.Mutator { 72 return &statePull{} 73 }