diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index a9f0724eb92b..36f3ab43700a 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -27,4 +27,7 @@ [#9443](https://github.com/pulumi/pulumi/pull/9443) - [auto/go] Fixed a race condition that could cause `Preview` to fail with "failed to get preview summary". - [#9467](https://github.com/pulumi/pulumi/pull/9467) \ No newline at end of file + [#9467](https://github.com/pulumi/pulumi/pull/9467) + +- [backend/filestate] - Fix a bug creating `stack.json.bak` files. + [#9476](https://github.com/pulumi/pulumi/pull/9476) \ No newline at end of file diff --git a/pkg/backend/filestate/backend_test.go b/pkg/backend/filestate/backend_test.go index fd268e2477b1..8089ac182e79 100644 --- a/pkg/backend/filestate/backend_test.go +++ b/pkg/backend/filestate/backend_test.go @@ -281,3 +281,47 @@ func TestCancel(t *testing.T) { err = lb.checkForLock(ctx, aStackRef) assert.NoError(t, err) } + +func TestRemoveMakesBackups(t *testing.T) { + t.Parallel() + + // Login to a temp dir filestate backend + tmpDir, err := ioutil.TempDir("", "filestatebackend") + assert.NoError(t, err) + b, err := New(cmdutil.Diag(), "file://"+filepath.ToSlash(tmpDir)) + assert.NoError(t, err) + ctx := context.Background() + + // Grab the bucket interface to test with + lb, ok := b.(*localBackend) + assert.True(t, ok) + assert.NotNil(t, lb) + + // Check that creating a new stack doesn't make a backup file + aStackRef, err := b.ParseStackReference("a") + assert.NoError(t, err) + aStack, err := b.CreateStack(ctx, aStackRef, nil) + assert.NoError(t, err) + assert.NotNil(t, aStack) + + // Check the stack file now exists, but the backup file doesn't + stackFileExists, err := lb.bucket.Exists(ctx, lb.stackPath(aStackRef.Name())) + assert.NoError(t, err) + assert.True(t, stackFileExists) + backupFileExists, err := lb.bucket.Exists(ctx, lb.stackPath(aStackRef.Name())+".bak") + assert.NoError(t, err) + assert.False(t, backupFileExists) + + // Now remove the stack + removed, err := b.RemoveStack(ctx, aStack, false) + assert.NoError(t, err) + assert.False(t, removed) + + // Check the stack file is now gone, but the backup file exists + stackFileExists, err = lb.bucket.Exists(ctx, lb.stackPath(aStackRef.Name())) + assert.NoError(t, err) + assert.False(t, stackFileExists) + backupFileExists, err = lb.bucket.Exists(ctx, lb.stackPath(aStackRef.Name())+".bak") + assert.NoError(t, err) + assert.True(t, backupFileExists) +} diff --git a/pkg/backend/filestate/state.go b/pkg/backend/filestate/state.go index f1fefe7e7394..2fc0dc4f8852 100644 --- a/pkg/backend/filestate/state.go +++ b/pkg/backend/filestate/state.go @@ -263,7 +263,7 @@ func backupTarget(bucket Bucket, file string, keepOriginal bool) string { contract.Require(file != "", "file") bck := file + ".bak" - err := bucket.Copy(context.TODO(), file, bck, nil) + err := bucket.Copy(context.TODO(), bck, file, nil) if err != nil { logging.V(5).Infof("error copying %s to %s: %s", file, bck, err) }