From 0009768c7f12e82de9ccefddd8e07cd48058b52c Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Mon, 12 Oct 2020 17:18:50 -0700 Subject: [PATCH] internal/depsfile: Update the dependency lock file atomically In this case, "atomic" means that there will be no situation where the file contains only part of the newContent data, and therefore other software monitoring the file for changes (using a mechanism like inotify) won't encounter a truncated file. It does _not_ mean that there can't be existing filehandles open against the old version of the file. On Windows systems the write will fail in that case, but on Unix systems the write will typically succeed but leave the existing filehandles still pointing at the old version of the file. They'll need to reopen the file in order to see the new content. --- internal/depsfile/locks_file.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/internal/depsfile/locks_file.go b/internal/depsfile/locks_file.go index e11bbcc2f..1fd7f5586 100644 --- a/internal/depsfile/locks_file.go +++ b/internal/depsfile/locks_file.go @@ -2,7 +2,6 @@ package depsfile import ( "fmt" - "io/ioutil" "os" "sort" @@ -15,6 +14,7 @@ import ( "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/internal/getproviders" + "github.com/hashicorp/terraform/internal/replacefile" "github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/version" ) @@ -108,11 +108,7 @@ func SaveLocksToFile(locks *Locks, filename string) tfdiags.Diagnostics { newContent := f.Bytes() - // TODO: Create the content in a new file and atomically pivot it into - // the target, so that there isn't a brief period where an incomplete - // file can be seen at the given location. - // But for now, this gets us started. - err := ioutil.WriteFile(filename, newContent, os.ModePerm) + err := replacefile.AtomicWriteFile(filename, newContent, os.ModePerm) if err != nil { diags = diags.Append(tfdiags.Sourceless( tfdiags.Error,