From 42095f2868e9655415136d19a2aa8d88da9ce4fd Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 29 Jan 2025 17:20:11 +0100 Subject: [PATCH 01/15] acc: Use real (cached) terraform in acceptance tests --- acceptance/.gitignore | 1 + acceptance/acceptance_test.go | 57 +++++--- acceptance/build/.gitignore | 1 - .../bundle/variables/git-branch/output.txt | 4 +- .../prepend-workspace-var/output.txt | 2 +- acceptance/install_terraform.py | 123 ++++++++++++++++++ acceptance/terraform/main.tf | 25 ++++ acceptance/terraform/output.txt | 69 ++++++++++ acceptance/terraform/script | 5 + acceptance/terraform/test.toml | 3 + 10 files changed, 265 insertions(+), 25 deletions(-) create mode 100644 acceptance/.gitignore delete mode 100644 acceptance/build/.gitignore create mode 100755 acceptance/install_terraform.py create mode 100644 acceptance/terraform/main.tf create mode 100644 acceptance/terraform/output.txt create mode 100644 acceptance/terraform/script create mode 100644 acceptance/terraform/test.toml diff --git a/acceptance/.gitignore b/acceptance/.gitignore new file mode 100644 index 0000000000..378eac25d3 --- /dev/null +++ b/acceptance/.gitignore @@ -0,0 +1 @@ +build diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index 60f7945dff..ccd0bb5420 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -76,6 +76,10 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int { cwd, err := os.Getwd() require.NoError(t, err) + // Download terraform and provider and create config; this also creates build directory. + RunCommand(t, []string{filepath.Join(cwd, "install_terraform.py")}, ".") + + buildDir := filepath.Join(cwd, "build") coverDir := os.Getenv("CLI_GOCOVERDIR") if coverDir != "" { @@ -92,7 +96,7 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int { t.Setenv("CMD_SERVER_URL", cmdServer.URL) execPath = filepath.Join(cwd, "bin", "callserver.py") } else { - execPath = BuildCLI(t, cwd, coverDir) + execPath = BuildCLI(t, buildDir, coverDir) } t.Setenv("CLI", execPath) @@ -122,11 +126,21 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int { homeDir := t.TempDir() // Do not read user's ~/.databrickscfg t.Setenv(env.HomeEnvVar(), homeDir) - - // Prevent CLI from downloading terraform in each test: - t.Setenv("DATABRICKS_TF_EXEC_PATH", tempHomeDir) } + terraformrcPath := filepath.Join(buildDir, ".terraformrc") + t.Setenv("TF_CLI_CONFIG_FILE", terraformrcPath) + t.Setenv("DATABRICKS_TF_CLI_CONFIG_FILE", terraformrcPath) + repls.Set(terraformrcPath, "DATABRICKS_TF_CLI_CONFIG_FILE") + + terraformExecPath := filepath.Join(buildDir, "terraform") + t.Setenv("DATABRICKS_TF_EXEC_PATH", terraformExecPath) + t.Setenv("TERRAFORM", terraformExecPath) + repls.Set(terraformExecPath, "$TERRAFORM") + + // do it last so that full paths match first: + repls.Set(buildDir, "$BUILD_DIR") + workspaceClient, err := databricks.NewWorkspaceClient() require.NoError(t, err) @@ -373,13 +387,12 @@ func readMergedScriptContents(t *testing.T, dir string) string { return strings.Join(prepares, "\n") } -func BuildCLI(t *testing.T, cwd, coverDir string) string { - execPath := filepath.Join(cwd, "build", "databricks") +func BuildCLI(t *testing.T, buildDir, coverDir string) string { + execPath := filepath.Join(buildDir, "databricks") if runtime.GOOS == "windows" { execPath += ".exe" } - start := time.Now() args := []string{ "go", "build", "-mod", "vendor", @@ -397,20 +410,8 @@ func BuildCLI(t *testing.T, cwd, coverDir string) string { args = append(args, "-buildvcs=false") } - cmd := exec.Command(args[0], args[1:]...) - cmd.Dir = ".." - out, err := cmd.CombinedOutput() - elapsed := time.Since(start) - t.Logf("%s took %s", args, elapsed) - require.NoError(t, err, "go build failed: %s: %s\n%s", args, err, out) - if len(out) > 0 { - t.Logf("go build output: %s: %s", args, out) - } - - // Quick check + warm up cache: - cmd = exec.Command(execPath, "--version") - out, err = cmd.CombinedOutput() - require.NoError(t, err, "%s --version failed: %s\n%s", execPath, err, out) + RunCommand(t, args, "..") + RunCommand(t, []string{execPath, "--version"}, ".") return execPath } @@ -548,3 +549,17 @@ func getUVDefaultCacheDir(t *testing.T) string { return cacheDir + "/uv" } } + +func RunCommand(t *testing.T, args []string, dir string) { + start := time.Now() + cmd := exec.Command(args[0], args[1:]...) + cmd.Dir = dir + out, err := cmd.CombinedOutput() + elapsed := time.Since(start) + t.Logf("%s took %s", args, elapsed) + + require.NoError(t, err, "%s failed: %s\n%s", args, err, out) + if len(out) > 0 { + t.Logf("%s output: %s", args, out) + } +} diff --git a/acceptance/build/.gitignore b/acceptance/build/.gitignore deleted file mode 100644 index a48b4db254..0000000000 --- a/acceptance/build/.gitignore +++ /dev/null @@ -1 +0,0 @@ -databricks diff --git a/acceptance/bundle/variables/git-branch/output.txt b/acceptance/bundle/variables/git-branch/output.txt index fb3ab805ac..5e7664f619 100644 --- a/acceptance/bundle/variables/git-branch/output.txt +++ b/acceptance/bundle/variables/git-branch/output.txt @@ -11,7 +11,7 @@ "name": "git", "target": "prod", "terraform": { - "exec_path": "$TMPHOME" + "exec_path": "$TERRAFORM" } }, "sync": { @@ -61,7 +61,7 @@ Validation OK! "name": "git", "target": "dev", "terraform": { - "exec_path": "$TMPHOME" + "exec_path": "$TERRAFORM" } }, "sync": { diff --git a/acceptance/bundle/variables/prepend-workspace-var/output.txt b/acceptance/bundle/variables/prepend-workspace-var/output.txt index fcaa25b4a0..ed6c2b2af2 100644 --- a/acceptance/bundle/variables/prepend-workspace-var/output.txt +++ b/acceptance/bundle/variables/prepend-workspace-var/output.txt @@ -7,7 +7,7 @@ }, "target": "dev", "terraform": { - "exec_path": "$TMPHOME" + "exec_path": "$TERRAFORM" } }, "resources": { diff --git a/acceptance/install_terraform.py b/acceptance/install_terraform.py new file mode 100755 index 0000000000..8a5a340e14 --- /dev/null +++ b/acceptance/install_terraform.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +""" +Script to set up terraform and databricks terraform provider in a local directory: + +- Download terraform. +- Download databricks provider. +- Write a .terraformrc config file that uses this directory. +- The config file contains env vars that need to be set so that databricks CLI uses this terraform and provider. +""" + +import os +import platform +import zipfile +import argparse +from pathlib import Path +from urllib.request import urlretrieve + +os_name = platform.system().lower() + +current_arch = platform.machine().lower() +arch_mapping = { + "x86_64": "amd64", + "amd64": "amd64", + "arm64": "arm64", + "aarch64": "arm64", +} +arch = arch_mapping.get(current_arch, current_arch) + +terraform_version = "1.5.5" +terraform_file = f"terraform_{terraform_version}_{os_name}_{arch}.zip" +terraform_url = f"https://releases.hashicorp.com/terraform/{terraform_version}/{terraform_file}" +terraform_binary = "terraform.exe" if os_name == "windows" else "terraform" + + +def retrieve(url, path): + if not path.exists(): + print(f"Downloading {url} -> {path}") + urlretrieve(url, path) + + +def read_version(path): + for line in path.open(): + if "ProviderVersion" in line: + # Expecting 'const ProviderVersion = "1.64.1"' + items = line.strip().split() + assert len(items) >= 3, items + assert items[-3:-1] == ["ProviderVersion", "="], items + version = items[-1].strip('"') + assert version, items + return version + raise SystemExit(f"Could not find ProviderVersion in {path}") + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--targetdir", default="build", type=Path) + parser.add_argument("--provider-version") + args = parser.parse_args() + target = args.targetdir + + if not args.provider_version: + version_file = Path(__file__).parent.parent / "bundle/internal/tf/codegen/schema/version.go" + assert version_file.exists(), version_file + terraform_provider_version = read_version(version_file) + print(f"Read version {terraform_provider_version} from {version_file}") + else: + terraform_provider_version = args.provider_version + + terraform_provider_file = f"terraform-provider-databricks_{terraform_provider_version}_{os_name}_{arch}.zip" + terraform_provider_url = ( + f"https://github.com/databricks/terraform-provider-databricks/releases/download/v{terraform_provider_version}/{terraform_provider_file}" + ) + + target.mkdir(exist_ok=True) + + zip_path = target / terraform_file + terraform_path = target / terraform_binary + terraform_provider_path = target / terraform_provider_file + + retrieve(terraform_url, zip_path) + retrieve(terraform_provider_url, terraform_provider_path) + + if not terraform_path.exists(): + print(f"Extracting {zip_path} -> {terraform_path}") + + with zipfile.ZipFile(zip_path, "r") as zip_ref: + zip_ref.extractall(target) + + terraform_path.chmod(0o755) + + tfplugins_path = target / "tfplugins" + provider_dir = Path(tfplugins_path / f"registry.terraform.io/databricks/databricks/{terraform_provider_version}/{os_name}_{arch}") + if not provider_dir.exists(): + print(f"Extracting {terraform_provider_path} -> {provider_dir}") + os.makedirs(provider_dir, exist_ok=True) + with zipfile.ZipFile(terraform_provider_path, "r") as zip_ref: + zip_ref.extractall(provider_dir) + + files = list(provider_dir.iterdir()) + assert files, provider_dir + + for f in files: + f.chmod(0o755) + + terraformrc_path = target / ".terraformrc" + if not terraformrc_path.exists(): + print(f"Writing {terraformrc_path} (see it for instructions)") + + terraformrc_path.write_text(f"""# Set these env variables before running databricks cli: +# export DATABRICKS_TF_CLI_CONFIG_FILE={terraformrc_path.absolute()} +# export DATABRICKS_TF_EXEC_PATH={terraform_path.absolute()} + +provider_installation {{ + filesystem_mirror {{ + path = "{tfplugins_path.absolute()}" + include = ["registry.terraform.io/databricks/databricks"] + }} +}} +""") + + +if __name__ == "__main__": + main() diff --git a/acceptance/terraform/main.tf b/acceptance/terraform/main.tf new file mode 100644 index 0000000000..93f665ff4a --- /dev/null +++ b/acceptance/terraform/main.tf @@ -0,0 +1,25 @@ +terraform { + required_providers { + databricks = { + source = "databricks/databricks" + version = "1.64.1" + } + } + + required_version = "= 1.5.5" +} + +provider "databricks" { + # Optionally, specify the Databricks host and token + # host = "https://" + # token = "" +} + +data "databricks_current_user" "me" { + # Retrieves the current user's information +} + +output "username" { + description = "Username" + value = "${data.databricks_current_user.me.user_name}" +} diff --git a/acceptance/terraform/output.txt b/acceptance/terraform/output.txt new file mode 100644 index 0000000000..8ce96d0904 --- /dev/null +++ b/acceptance/terraform/output.txt @@ -0,0 +1,69 @@ + +>>> $TERRAFORM init -no-color +Timestamp [INFO] Terraform version: 1.5.5 +Timestamp [DEBUG] using github.com/hashicorp/go-tfe v1.26.0 +Timestamp [DEBUG] using github.com/hashicorp/hcl/v2 v2.16.2 +Timestamp [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.0 +Timestamp [DEBUG] using github.com/zclconf/go-cty v1.12.2 +Timestamp [INFO] Go runtime version: go1.20.7 +Timestamp [INFO] CLI args: []string{"$TERRAFORM", "init", "-no-color"} +Timestamp [DEBUG] Attempting to open CLI config file: DATABRICKS_TF_CLI_CONFIG_FILE +Timestamp [INFO] Loading CLI configuration from DATABRICKS_TF_CLI_CONFIG_FILE +Timestamp [DEBUG] Not reading CLI config directory because config location is overridden by environment variable +Timestamp [DEBUG] Explicit provider installation configuration is set +Timestamp [INFO] CLI command args: []string{"init", "-no-color"} + +Initializing the backend... +Timestamp [DEBUG] New state was assigned lineage "[UUID]" +Timestamp [DEBUG] checking for provisioner in "." +Timestamp [DEBUG] checking for provisioner in "$BUILD_DIR" + +Initializing provider plugins... +- Finding databricks/databricks versions matching "1.64.1"... +- Installing databricks/databricks v1.64.1... +- Installed databricks/databricks v1.64.1 (unauthenticated) + +Terraform has created a lock file .terraform.lock.hcl to record the provider +selections it made above. Include this file in your version control repository +so that Terraform can guarantee to make the same selections by default when +you run "terraform init" in the future. + + +Warning: Incomplete lock file information for providers + +Due to your customized provider installation methods, Terraform was forced to +calculate lock file checksums locally for the following providers: + - databricks/databricks + +The current .terraform.lock.hcl file only includes checksums for +darwin_arm64, so Terraform running on another platform will fail to install +these providers. + +To calculate additional checksums for another platform, run: + terraform providers lock -platform=linux_amd64 +(where linux_amd64 is the platform to generate) + +Terraform has been successfully initialized! + +You may now begin working with Terraform. Try running "terraform plan" to see +any changes that are required for your infrastructure. All Terraform commands +should now work. + +If you ever set or change modules or backend configuration for Terraform, +rerun this command to reinitialize your working directory. If you forget, other +commands will detect it and remind you to do so if necessary. + +>>> $TERRAFORM plan -no-color +data.databricks_current_user.me: Reading... +data.databricks_current_user.me: Read complete after 0s [id=$USER.Id] + +Changes to Outputs: + + username = "$USERNAME" + +You can apply this plan to save these new output values to the Terraform +state, without changing any real infrastructure. + +───────────────────────────────────────────────────────────────────────────── + +Note: You didn't use the -out option to save this plan, so Terraform can't +guarantee to take exactly these actions if you run "terraform apply" now. diff --git a/acceptance/terraform/script b/acceptance/terraform/script new file mode 100644 index 0000000000..a78bb7dc2c --- /dev/null +++ b/acceptance/terraform/script @@ -0,0 +1,5 @@ +export TF_LOG=DEBUG +trace $TERRAFORM init -no-color +export TF_LOG=WARN +trace $TERRAFORM plan -no-color +rm -fr .terraform.lock.hcl .terraform diff --git a/acceptance/terraform/test.toml b/acceptance/terraform/test.toml new file mode 100644 index 0000000000..da94548411 --- /dev/null +++ b/acceptance/terraform/test.toml @@ -0,0 +1,3 @@ +[[Repls]] +Old = '\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d+\+\d+' +New = 'Timestamp' From 153442285cee3684fafe0608cd0e49f5b267f8af Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 29 Jan 2025 22:52:26 +0100 Subject: [PATCH 02/15] tweak timestamp regex --- acceptance/terraform/test.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance/terraform/test.toml b/acceptance/terraform/test.toml index da94548411..c63490b35c 100644 --- a/acceptance/terraform/test.toml +++ b/acceptance/terraform/test.toml @@ -1,3 +1,3 @@ [[Repls]] -Old = '\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d+\+\d+' +Old = '\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d+(\+\d+|Z|)' New = 'Timestamp' From 09a686f4458819ff3061bb3e7658e9c0bc39431f Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 09:52:31 +0100 Subject: [PATCH 03/15] filter out platform-specific messages to fix this on ubuntu-latest: -The current .terraform.lock.hcl file only includes checksums for -darwin_arm64, so Terraform running on another platform will fail to install -these providers. +The current .terraform.lock.hcl file only includes checksums for linux_amd64, +so Terraform running on another platform will fail to install these +providers. --- acceptance/terraform/output.txt | 12 +++++------- acceptance/terraform/script | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/acceptance/terraform/output.txt b/acceptance/terraform/output.txt index 8ce96d0904..f89abdafa1 100644 --- a/acceptance/terraform/output.txt +++ b/acceptance/terraform/output.txt @@ -1,23 +1,23 @@ ->>> $TERRAFORM init -no-color +>>> $TERRAFORM init -no-color -get=false Timestamp [INFO] Terraform version: 1.5.5 Timestamp [DEBUG] using github.com/hashicorp/go-tfe v1.26.0 Timestamp [DEBUG] using github.com/hashicorp/hcl/v2 v2.16.2 Timestamp [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.0 Timestamp [DEBUG] using github.com/zclconf/go-cty v1.12.2 Timestamp [INFO] Go runtime version: go1.20.7 -Timestamp [INFO] CLI args: []string{"$TERRAFORM", "init", "-no-color"} +Timestamp [INFO] CLI args: []string{"$TERRAFORM", "init", "-no-color", "-get=false"} Timestamp [DEBUG] Attempting to open CLI config file: DATABRICKS_TF_CLI_CONFIG_FILE Timestamp [INFO] Loading CLI configuration from DATABRICKS_TF_CLI_CONFIG_FILE Timestamp [DEBUG] Not reading CLI config directory because config location is overridden by environment variable Timestamp [DEBUG] Explicit provider installation configuration is set -Timestamp [INFO] CLI command args: []string{"init", "-no-color"} - -Initializing the backend... +Timestamp [INFO] CLI command args: []string{"init", "-no-color", "-get=false"} Timestamp [DEBUG] New state was assigned lineage "[UUID]" Timestamp [DEBUG] checking for provisioner in "." Timestamp [DEBUG] checking for provisioner in "$BUILD_DIR" +Initializing the backend... + Initializing provider plugins... - Finding databricks/databricks versions matching "1.64.1"... - Installing databricks/databricks v1.64.1... @@ -35,8 +35,6 @@ Due to your customized provider installation methods, Terraform was forced to calculate lock file checksums locally for the following providers: - databricks/databricks -The current .terraform.lock.hcl file only includes checksums for -darwin_arm64, so Terraform running on another platform will fail to install these providers. To calculate additional checksums for another platform, run: diff --git a/acceptance/terraform/script b/acceptance/terraform/script index a78bb7dc2c..7871e637f9 100644 --- a/acceptance/terraform/script +++ b/acceptance/terraform/script @@ -1,5 +1,18 @@ export TF_LOG=DEBUG -trace $TERRAFORM init -no-color + + +# Want to filter out these message: +# Mac: +# The current .terraform.lock.hcl file only includes checksums for +# darwin_arm64, so Terraform running on another platform will fail to install +# these providers. +# +# Linux: +# The current .terraform.lock.hcl file only includes checksums for linux_amd64, +# so Terraform running on another platform will fail to install these +# providers + +trace $TERRAFORM init -no-color -get=false | grep -v 'includes checksums for' | grep -v 'so Terraform running on another' export TF_LOG=WARN trace $TERRAFORM plan -no-color rm -fr .terraform.lock.hcl .terraform From a5c4f6caa1c7e2f7bd4951200a3aeab86563946c Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 10:00:34 +0100 Subject: [PATCH 04/15] fix windows --- acceptance/acceptance_test.go | 6 +++++- acceptance/install_terraform.py | 12 ++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index ccd0bb5420..a9b95887b4 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -77,7 +77,11 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int { require.NoError(t, err) // Download terraform and provider and create config; this also creates build directory. - RunCommand(t, []string{filepath.Join(cwd, "install_terraform.py")}, ".") + if runtime.GOOS == "windows" { + RunCommand(t, []string{"python", filepath.Join(cwd, "install_terraform.py")}, ".") + } else { + RunCommand(t, []string{filepath.Join(cwd, "install_terraform.py")}, ".") + } buildDir := filepath.Join(cwd, "build") coverDir := os.Getenv("CLI_GOCOVERDIR") diff --git a/acceptance/install_terraform.py b/acceptance/install_terraform.py index 8a5a340e14..74beb436af 100755 --- a/acceptance/install_terraform.py +++ b/acceptance/install_terraform.py @@ -17,14 +17,10 @@ os_name = platform.system().lower() -current_arch = platform.machine().lower() -arch_mapping = { - "x86_64": "amd64", - "amd64": "amd64", - "arm64": "arm64", - "aarch64": "arm64", -} -arch = arch_mapping.get(current_arch, current_arch) +arch = platform.machine().lower() +if os_name == 'windows' and arch not in ('386', 'amd64'): + # terraform 1.5.5 only has builds for these two. + arch = 'amd64' terraform_version = "1.5.5" terraform_file = f"terraform_{terraform_version}_{os_name}_{arch}.zip" From 913c4e61ef342b7e621e7aa807f6844059a80aa2 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 10:02:13 +0100 Subject: [PATCH 05/15] filter out more --- acceptance/terraform/output.txt | 1 - acceptance/terraform/script | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/acceptance/terraform/output.txt b/acceptance/terraform/output.txt index f89abdafa1..82895990dd 100644 --- a/acceptance/terraform/output.txt +++ b/acceptance/terraform/output.txt @@ -35,7 +35,6 @@ Due to your customized provider installation methods, Terraform was forced to calculate lock file checksums locally for the following providers: - databricks/databricks -these providers. To calculate additional checksums for another platform, run: terraform providers lock -platform=linux_amd64 diff --git a/acceptance/terraform/script b/acceptance/terraform/script index 7871e637f9..7c2f4ed1dd 100644 --- a/acceptance/terraform/script +++ b/acceptance/terraform/script @@ -10,9 +10,9 @@ export TF_LOG=DEBUG # Linux: # The current .terraform.lock.hcl file only includes checksums for linux_amd64, # so Terraform running on another platform will fail to install these -# providers +# providers. -trace $TERRAFORM init -no-color -get=false | grep -v 'includes checksums for' | grep -v 'so Terraform running on another' +trace $TERRAFORM init -no-color -get=false | grep -v 'includes checksums for' | grep -v 'so Terraform running on another' | grep -v 'providers\.' export TF_LOG=WARN trace $TERRAFORM plan -no-color rm -fr .terraform.lock.hcl .terraform From ab7b750cf5b4e3423c247d2062d07200eafb6d1c Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 10:02:54 +0100 Subject: [PATCH 06/15] ruff --- acceptance/install_terraform.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acceptance/install_terraform.py b/acceptance/install_terraform.py index 74beb436af..b4fbdef82c 100755 --- a/acceptance/install_terraform.py +++ b/acceptance/install_terraform.py @@ -18,9 +18,9 @@ os_name = platform.system().lower() arch = platform.machine().lower() -if os_name == 'windows' and arch not in ('386', 'amd64'): +if os_name == "windows" and arch not in ("386", "amd64"): # terraform 1.5.5 only has builds for these two. - arch = 'amd64' + arch = "amd64" terraform_version = "1.5.5" terraform_file = f"terraform_{terraform_version}_{os_name}_{arch}.zip" From dbff077fba9dd2242a7ad429f50d11922ec4dc9d Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 10:04:09 +0100 Subject: [PATCH 07/15] restore mapping x86_64 -> amd64 --- acceptance/install_terraform.py | 1 + 1 file changed, 1 insertion(+) diff --git a/acceptance/install_terraform.py b/acceptance/install_terraform.py index b4fbdef82c..2f0e9608ac 100755 --- a/acceptance/install_terraform.py +++ b/acceptance/install_terraform.py @@ -18,6 +18,7 @@ os_name = platform.system().lower() arch = platform.machine().lower() +arch = {"x86_64": "amd64"}.get(arch, arch) if os_name == "windows" and arch not in ("386", "amd64"): # terraform 1.5.5 only has builds for these two. arch = "amd64" From 2a2f70a60278213535d807e66265e8df5e43db6c Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 10:12:44 +0100 Subject: [PATCH 08/15] Add $ before replaced string --- acceptance/acceptance_test.go | 2 +- acceptance/terraform/output.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index a9b95887b4..ed2f985d85 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -135,7 +135,7 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int { terraformrcPath := filepath.Join(buildDir, ".terraformrc") t.Setenv("TF_CLI_CONFIG_FILE", terraformrcPath) t.Setenv("DATABRICKS_TF_CLI_CONFIG_FILE", terraformrcPath) - repls.Set(terraformrcPath, "DATABRICKS_TF_CLI_CONFIG_FILE") + repls.Set(terraformrcPath, "$DATABRICKS_TF_CLI_CONFIG_FILE") terraformExecPath := filepath.Join(buildDir, "terraform") t.Setenv("DATABRICKS_TF_EXEC_PATH", terraformExecPath) diff --git a/acceptance/terraform/output.txt b/acceptance/terraform/output.txt index 82895990dd..74fbfca99a 100644 --- a/acceptance/terraform/output.txt +++ b/acceptance/terraform/output.txt @@ -7,8 +7,8 @@ Timestamp [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.0 Timestamp [DEBUG] using github.com/zclconf/go-cty v1.12.2 Timestamp [INFO] Go runtime version: go1.20.7 Timestamp [INFO] CLI args: []string{"$TERRAFORM", "init", "-no-color", "-get=false"} -Timestamp [DEBUG] Attempting to open CLI config file: DATABRICKS_TF_CLI_CONFIG_FILE -Timestamp [INFO] Loading CLI configuration from DATABRICKS_TF_CLI_CONFIG_FILE +Timestamp [DEBUG] Attempting to open CLI config file: $DATABRICKS_TF_CLI_CONFIG_FILE +Timestamp [INFO] Loading CLI configuration from $DATABRICKS_TF_CLI_CONFIG_FILE Timestamp [DEBUG] Not reading CLI config directory because config location is overridden by environment variable Timestamp [DEBUG] Explicit provider installation configuration is set Timestamp [INFO] CLI command args: []string{"init", "-no-color", "-get=false"} From c06d80e10deec2f5d26b6bc1930540b315ae28ae Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 10:21:27 +0100 Subject: [PATCH 09/15] use json to serialize backslashes better and print terraformrc for debugging --- acceptance/install_terraform.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/acceptance/install_terraform.py b/acceptance/install_terraform.py index 2f0e9608ac..177e3dd6c9 100755 --- a/acceptance/install_terraform.py +++ b/acceptance/install_terraform.py @@ -12,6 +12,7 @@ import platform import zipfile import argparse +import json from pathlib import Path from urllib.request import urlretrieve @@ -101,19 +102,20 @@ def main(): terraformrc_path = target / ".terraformrc" if not terraformrc_path.exists(): - print(f"Writing {terraformrc_path} (see it for instructions)") - - terraformrc_path.write_text(f"""# Set these env variables before running databricks cli: + path = json.dumps(str(tfplugins_path.absolute())) + text = f"""# Set these env variables before running databricks cli: # export DATABRICKS_TF_CLI_CONFIG_FILE={terraformrc_path.absolute()} # export DATABRICKS_TF_EXEC_PATH={terraform_path.absolute()} provider_installation {{ filesystem_mirror {{ - path = "{tfplugins_path.absolute()}" + path = {path} include = ["registry.terraform.io/databricks/databricks"] }} }} -""") +""" + print(f"Writing {terraformrc_path}:\n{text}") + terraformrc_path.write_text(text) if __name__ == "__main__": From 0dc7ffb1f2afeb47627f591fb58b5f2a78a6d4bd Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 10:28:49 +0100 Subject: [PATCH 10/15] Use SetPath for paths --- acceptance/acceptance_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index ed2f985d85..ee46294e4c 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -135,15 +135,15 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int { terraformrcPath := filepath.Join(buildDir, ".terraformrc") t.Setenv("TF_CLI_CONFIG_FILE", terraformrcPath) t.Setenv("DATABRICKS_TF_CLI_CONFIG_FILE", terraformrcPath) - repls.Set(terraformrcPath, "$DATABRICKS_TF_CLI_CONFIG_FILE") + repls.SetPath(terraformrcPath, "$DATABRICKS_TF_CLI_CONFIG_FILE") terraformExecPath := filepath.Join(buildDir, "terraform") t.Setenv("DATABRICKS_TF_EXEC_PATH", terraformExecPath) t.Setenv("TERRAFORM", terraformExecPath) - repls.Set(terraformExecPath, "$TERRAFORM") + repls.SetPath(terraformExecPath, "$TERRAFORM") // do it last so that full paths match first: - repls.Set(buildDir, "$BUILD_DIR") + repls.SetPath(buildDir, "$BUILD_DIR") workspaceClient, err := databricks.NewWorkspaceClient() require.NoError(t, err) From 78433f9d44efdddcef988e4559f2f275b16fe4be Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 11:16:32 +0100 Subject: [PATCH 11/15] per-arch build directory --- acceptance/acceptance_test.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index ee46294e4c..4b70a9f9df 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -76,14 +76,11 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int { cwd, err := os.Getwd() require.NoError(t, err) + buildDir := filepath.Join(cwd, "build", fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH)) + // Download terraform and provider and create config; this also creates build directory. - if runtime.GOOS == "windows" { - RunCommand(t, []string{"python", filepath.Join(cwd, "install_terraform.py")}, ".") - } else { - RunCommand(t, []string{filepath.Join(cwd, "install_terraform.py")}, ".") - } + RunCommand(t, []string{"python3", filepath.Join(cwd, "install_terraform.py"), "--targetdir", buildDir}, ".") - buildDir := filepath.Join(cwd, "build") coverDir := os.Getenv("CLI_GOCOVERDIR") if coverDir != "" { From ca8026ea96f7742ebb8753d5bd0e60d1dd3f032f Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 11:16:48 +0100 Subject: [PATCH 12/15] support --targetdir a/b/c --- acceptance/install_terraform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance/install_terraform.py b/acceptance/install_terraform.py index 177e3dd6c9..4cf6a97290 100755 --- a/acceptance/install_terraform.py +++ b/acceptance/install_terraform.py @@ -69,7 +69,7 @@ def main(): f"https://github.com/databricks/terraform-provider-databricks/releases/download/v{terraform_provider_version}/{terraform_provider_file}" ) - target.mkdir(exist_ok=True) + target.mkdir(exist_ok=True, parents=True) zip_path = target / terraform_file terraform_path = target / terraform_binary From 4e4609c0282bc57e0cdd860b20d6542b99893411 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 11:17:04 +0100 Subject: [PATCH 13/15] exclude debuglog - too different on windows --- acceptance/terraform/output.txt | 15 --------------- acceptance/terraform/script | 4 ---- 2 files changed, 19 deletions(-) diff --git a/acceptance/terraform/output.txt b/acceptance/terraform/output.txt index 74fbfca99a..c3d453ea5f 100644 --- a/acceptance/terraform/output.txt +++ b/acceptance/terraform/output.txt @@ -1,20 +1,5 @@ >>> $TERRAFORM init -no-color -get=false -Timestamp [INFO] Terraform version: 1.5.5 -Timestamp [DEBUG] using github.com/hashicorp/go-tfe v1.26.0 -Timestamp [DEBUG] using github.com/hashicorp/hcl/v2 v2.16.2 -Timestamp [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.0 -Timestamp [DEBUG] using github.com/zclconf/go-cty v1.12.2 -Timestamp [INFO] Go runtime version: go1.20.7 -Timestamp [INFO] CLI args: []string{"$TERRAFORM", "init", "-no-color", "-get=false"} -Timestamp [DEBUG] Attempting to open CLI config file: $DATABRICKS_TF_CLI_CONFIG_FILE -Timestamp [INFO] Loading CLI configuration from $DATABRICKS_TF_CLI_CONFIG_FILE -Timestamp [DEBUG] Not reading CLI config directory because config location is overridden by environment variable -Timestamp [DEBUG] Explicit provider installation configuration is set -Timestamp [INFO] CLI command args: []string{"init", "-no-color", "-get=false"} -Timestamp [DEBUG] New state was assigned lineage "[UUID]" -Timestamp [DEBUG] checking for provisioner in "." -Timestamp [DEBUG] checking for provisioner in "$BUILD_DIR" Initializing the backend... diff --git a/acceptance/terraform/script b/acceptance/terraform/script index 7c2f4ed1dd..78e35049d1 100644 --- a/acceptance/terraform/script +++ b/acceptance/terraform/script @@ -1,6 +1,3 @@ -export TF_LOG=DEBUG - - # Want to filter out these message: # Mac: # The current .terraform.lock.hcl file only includes checksums for @@ -13,6 +10,5 @@ export TF_LOG=DEBUG # providers. trace $TERRAFORM init -no-color -get=false | grep -v 'includes checksums for' | grep -v 'so Terraform running on another' | grep -v 'providers\.' -export TF_LOG=WARN trace $TERRAFORM plan -no-color rm -fr .terraform.lock.hcl .terraform From bbedfbec9643e0daa5e410952723c847251c2588 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 11:25:47 +0100 Subject: [PATCH 14/15] Clean up timestamp replacement, not needed since detailed logs removed from output --- acceptance/terraform/test.toml | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 acceptance/terraform/test.toml diff --git a/acceptance/terraform/test.toml b/acceptance/terraform/test.toml deleted file mode 100644 index c63490b35c..0000000000 --- a/acceptance/terraform/test.toml +++ /dev/null @@ -1,3 +0,0 @@ -[[Repls]] -Old = '\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d+(\+\d+|Z|)' -New = 'Timestamp' From e9e47c5bd2083347990c852d245626a35bc59e54 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 30 Jan 2025 11:29:27 +0100 Subject: [PATCH 15/15] Use terraform.exe on Windows --- acceptance/acceptance_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index 4b70a9f9df..59eaf5b995 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -135,6 +135,9 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int { repls.SetPath(terraformrcPath, "$DATABRICKS_TF_CLI_CONFIG_FILE") terraformExecPath := filepath.Join(buildDir, "terraform") + if runtime.GOOS == "windows" { + terraformExecPath += ".exe" + } t.Setenv("DATABRICKS_TF_EXEC_PATH", terraformExecPath) t.Setenv("TERRAFORM", terraformExecPath) repls.SetPath(terraformExecPath, "$TERRAFORM")