From 89eeaed0a0b84f7f26a57b79692d1293117c5dc8 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Wed, 17 Jul 2019 08:39:37 -0400 Subject: [PATCH] [WIP] backend/enhanced: start with absolute configuration path (#22096) * 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. * 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 | 9 ++++- backend/remote/backend_plan_test.go | 57 ++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/backend/remote/backend_plan.go b/backend/remote/backend_plan.go index 200f7fd8d..9e73587ac 100644 --- a/backend/remote/backend_plan.go +++ b/backend/remote/backend_plan.go @@ -138,11 +138,18 @@ func (b *Remote) plan(stopCtx, cancelCtx context.Context, op *backend.Operation, var configDir string if op.ConfigDir != "" { + // 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. configDir = filepath.Clean(strings.TrimSuffix( - filepath.Clean(op.ConfigDir), + filepath.Clean(configDir), filepath.Clean(w.WorkingDirectory), )) } else { diff --git a/backend/remote/backend_plan_test.go b/backend/remote/backend_plan_test.go index fb6359993..f3ae3bb83 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()