Skip to content

Commit 182b766

Browse files
authored
Terraform provider cache support (#181)
* mount the tf cache directory if you have set it * mount in the same path than the host * test
1 parent af6b7b9 commit 182b766

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

leverage/container.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import json
2+
import os
23
from pathlib import Path
34
from datetime import datetime
4-
from datetime import timedelta
5-
import os
65

76
import hcl2
87
from click.exceptions import Exit
@@ -421,15 +420,24 @@ def __init__(self, client):
421420
"AWS_CACHE_DIR": f"{self.guest_aws_credentials_dir}/cache",
422421
"SSO_CACHE_DIR": f"{self.guest_aws_credentials_dir}/sso/cache",
423422
"SCRIPT_LOG_LEVEL": get_script_log_level(),
424-
"MFA_SCRIPT_LOG_LEVEL": get_script_log_level(), # Legacy
425-
"SSH_AUTH_SOCK": '' if SSH_AUTH_SOCK is None else '/ssh-agent'
423+
"MFA_SCRIPT_LOG_LEVEL": get_script_log_level(), # Legacy
424+
"SSH_AUTH_SOCK": '' if SSH_AUTH_SOCK is None else '/ssh-agent',
426425
}
427426
self.entrypoint = self.TF_BINARY
428427
self.mounts = [
429428
Mount(source=self.root_dir.as_posix(), target=self.guest_base_path, type="bind"),
430429
Mount(source=self.host_aws_credentials_dir.as_posix(), target=self.guest_aws_credentials_dir, type="bind"),
431-
Mount(source=(self.home / ".gitconfig").as_posix(), target="/etc/gitconfig", type="bind")
430+
Mount(source=(self.home / ".gitconfig").as_posix(), target="/etc/gitconfig", type="bind"),
432431
]
432+
# if you have set the tf plugin cache locally
433+
if tf_cache_dir := os.getenv("TF_PLUGIN_CACHE_DIR"):
434+
# then mount it too into the container
435+
self.environment["TF_PLUGIN_CACHE_DIR"] = tf_cache_dir
436+
# given that terraform use symlinks to point from the .terraform folder into the plugin folder
437+
# we need to use the same directory inside the container
438+
# otherwise symlinks will be broken once outside the container
439+
# which will break terraform usage outside Leverage
440+
self.mounts.append(Mount(source=tf_cache_dir, target=tf_cache_dir, type="bind"))
433441
if SSH_AUTH_SOCK is not None:
434442
self.mounts.append(Mount(source=SSH_AUTH_SOCK, target="/ssh-agent", type="bind"))
435443

@@ -533,7 +541,6 @@ def _prepare_container(self):
533541
"AWS_CONFIG_FILE": self.environment.get("AWS_CONFIG_FILE").replace("tmp", ".aws"),
534542
})
535543

536-
537544
logger.debug(f"[bold cyan]Running with entrypoint:[/bold cyan] {self.entrypoint}")
538545

539546
def check_for_layer_location(self):
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from unittest.mock import MagicMock, Mock, patch
2+
3+
from leverage.container import TerraformContainer
4+
5+
FAKE_ENV = {"TERRAFORM_IMAGE_TAG": "test", "PROJECT": "test"}
6+
FAKE_HOST_CONFIG = {
7+
"NetworkMode": "default",
8+
"SecurityOpt": ["label:disable"],
9+
"Mounts": [],
10+
}
11+
12+
13+
@patch("os.getenv", Mock(return_value="/home/testing/.terraform/cache"))
14+
def test_tf_plugin_cache_dir(muted_click_context):
15+
"""
16+
Given `TF_PLUGIN_CACHE_DIR` is set as an env var on the host
17+
we expect it to be on the container too, and also as a mounted folder.
18+
"""
19+
mocked_client = MagicMock()
20+
mocked_client.api.create_host_config.return_value = FAKE_HOST_CONFIG
21+
with patch("leverage.container.load_env", return_value=FAKE_ENV):
22+
container = TerraformContainer(mocked_client)
23+
container._run = Mock()
24+
25+
# call any command to trigger a container creation
26+
container.start_shell()
27+
container_args = container.client.api.create_container.call_args[1]
28+
29+
# make sure the env var is on place
30+
assert container_args["environment"]["TF_PLUGIN_CACHE_DIR"] == "/home/testing/.terraform/cache"
31+
32+
# and the cache folder mounted
33+
assert next(m for m in container_args["host_config"]["Mounts"] if m["Target"] == "/home/testing/.terraform/cache")

0 commit comments

Comments
 (0)