From 5f0444cdc80099b5857c2704c8061f087793525c Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Tue, 16 Jul 2019 16:19:48 -0400 Subject: [PATCH 1/2] backend/enhanced: start with absolute config path We recently started normalizing the config path before all "command" operations, which was necessary for consistency but had unexpected consequences for remote backend operations, specifically when a vcs root with a working directory are configured. This PR de-normalizes the path back to an absolute path. --- backend/remote/backend_plan.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/remote/backend_plan.go b/backend/remote/backend_plan.go index 200f7fd8dfed..ebde3dfe6f76 100644 --- a/backend/remote/backend_plan.go +++ b/backend/remote/backend_plan.go @@ -138,11 +138,13 @@ func (b *Remote) plan(stopCtx, cancelCtx context.Context, op *backend.Operation, var configDir string if op.ConfigDir != "" { + // de-normalize the config path + configDir, err = filepath.Abs(op.ConfigDir) // Make sure to take the working directory into account by removing // the working directory from the current path. This will result in // a path that points to the expected root of the workspace. configDir = filepath.Clean(strings.TrimSuffix( - filepath.Clean(op.ConfigDir), + filepath.Clean(configDir), filepath.Clean(w.WorkingDirectory), )) } else { From 77dcc0b343093c3d1c7420901019370be4980c84 Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Wed, 17 Jul 2019 11:33:39 +0200 Subject: [PATCH 2/2] Check the error and add a test It turned out all required logic was already present, so I just needed to add a test for this specific use case. --- backend/remote/backend_plan.go | 7 +++- backend/remote/backend_plan_test.go | 57 ++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/backend/remote/backend_plan.go b/backend/remote/backend_plan.go index ebde3dfe6f76..9e73587ac186 100644 --- a/backend/remote/backend_plan.go +++ b/backend/remote/backend_plan.go @@ -138,8 +138,13 @@ func (b *Remote) plan(stopCtx, cancelCtx context.Context, op *backend.Operation, var configDir string if op.ConfigDir != "" { - // de-normalize the config path + // De-normalize the configuration directory path. configDir, err = filepath.Abs(op.ConfigDir) + if err != nil { + return nil, generalError( + "Failed to get absolute path of the configuration directory: %v", err) + } + // Make sure to take the working directory into account by removing // the working directory from the current path. This will result in // a path that points to the expected root of the workspace. diff --git a/backend/remote/backend_plan_test.go b/backend/remote/backend_plan_test.go index fb63599930f7..f3ae3bb8358d 100644 --- a/backend/remote/backend_plan_test.go +++ b/backend/remote/backend_plan_test.go @@ -622,7 +622,7 @@ func TestRemote_planWithWorkingDirectory(t *testing.T) { WorkingDirectory: tfe.String("terraform"), } - // Configure the workspace to use a custom working direcrtory. + // Configure the workspace to use a custom working directory. _, err := b.client.Workspaces.Update(context.Background(), b.organization, b.workspace, options) if err != nil { t.Fatalf("error configuring working directory: %v", err) @@ -655,6 +655,61 @@ func TestRemote_planWithWorkingDirectory(t *testing.T) { } } +func TestRemote_planWithWorkingDirectoryFromCurrentPath(t *testing.T) { + b, bCleanup := testBackendDefault(t) + defer bCleanup() + + options := tfe.WorkspaceUpdateOptions{ + WorkingDirectory: tfe.String("terraform"), + } + + // Configure the workspace to use a custom working directory. + _, err := b.client.Workspaces.Update(context.Background(), b.organization, b.workspace, options) + if err != nil { + t.Fatalf("error configuring working directory: %v", err) + } + + wd, err := os.Getwd() + if err != nil { + t.Fatalf("error getting current working directory: %v", err) + } + + // We need to change into the configuration directory to make sure + // the logic to upload the correct slug is working as expected. + if err := os.Chdir("./testdata/plan-with-working-directory/terraform"); err != nil { + t.Fatalf("error changing directory: %v", err) + } + defer os.Chdir(wd) // Make sure we change back again when were done. + + // For this test we need to give our current directory instead of the + // full path to the configuration as we already changed directories. + op, configCleanup := testOperationPlan(t, ".") + defer configCleanup() + + op.Workspace = backend.DefaultStateName + + run, err := b.Operation(context.Background(), op) + if err != nil { + t.Fatalf("error starting operation: %v", err) + } + + <-run.Done() + if run.Result != backend.OperationSuccess { + t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String()) + } + if run.PlanEmpty { + t.Fatalf("expected a non-empty plan") + } + + output := b.CLI.(*cli.MockUi).OutputWriter.String() + if !strings.Contains(output, "Running plan in the remote backend") { + t.Fatalf("expected remote backend header in output: %s", output) + } + if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") { + t.Fatalf("expected plan summery in output: %s", output) + } +} + func TestRemote_planPolicyPass(t *testing.T) { b, bCleanup := testBackendDefault(t) defer bCleanup()