Skip to content

Commit 6a370a2

Browse files
committed
Define ANSIBLE_HOME to isolate from user environment
1 parent 306fbe9 commit 6a370a2

File tree

4 files changed

+37
-20
lines changed

4 files changed

+37
-20
lines changed

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"source.fixAll": "explicit",
1111
"source.organizeImports": "explicit"
1212
},
13-
"editor.defaultFormatter": "ms-python.black-formatter",
13+
"editor.defaultFormatter": "charliermarsh.ruff",
1414
"editor.formatOnSave": true
1515
},
1616
"editor.formatOnSave": true,

src/ansible_compat/prerun.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
11
"""Utilities for configuring ansible runtime environment."""
22

3-
import hashlib
43
import os
4+
import warnings
55
from pathlib import Path
66

77

88
def get_cache_dir(project_dir: Path) -> Path:
9-
"""Compute cache directory to be used based on project path."""
10-
# we only use the basename instead of the full path in order to ensure that
11-
# we would use the same key regardless the location of the user home
12-
# directory or where the project is clones (as long the project folder uses
13-
# the same name).
14-
basename = project_dir.resolve().name.encode(encoding="utf-8")
15-
# 6 chars of entropy should be enough
16-
cache_key = hashlib.sha256(basename).hexdigest()[:6]
17-
cache_dir = (
18-
Path(os.getenv("XDG_CACHE_HOME", "~/.cache")).expanduser()
19-
/ "ansible-compat"
20-
/ cache_key
21-
)
9+
"""Compute cache directory to be used based on project path.
10+
11+
If isolated=True, it will ensure ANSIBLE_HOME is defined.
12+
"""
13+
ansible_home: Path
14+
if "ANSIBLE_HOME" in os.environ:
15+
cache_dir = Path(os.environ["ANSIBLE_HOME"])
16+
ansible_home = cache_dir
17+
elif "VIRTUAL_ENV" in os.environ:
18+
cache_dir = Path(os.environ["VIRTUAL_ENV"]) / ".ansible"
19+
ansible_home = cache_dir
20+
msg = f"ANSIBLE_HOME is not set, will will define it to {ansible_home} to ensure test isolation."
21+
warnings.warn(msg, stacklevel=1)
22+
os.environ["ANSIBLE_HOME"] = ansible_home.as_posix()
23+
else:
24+
cache_dir = Path("~/.ansible").expanduser() / ".ansible"
25+
ansible_home = cache_dir
26+
27+
# create expected directory structure in order to avoid possible warnings
28+
# or errors from ansible (ansible-galaxy in particular)
29+
for subdir in ("roles",):
30+
(Path(ansible_home) / subdir).mkdir(parents=True, exist_ok=True)
31+
2232
return cache_dir

src/ansible_compat/runtime.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ def __init__(
208208
if "PYTHONWARNINGS" not in self.environ: # pragma: no cover
209209
self.environ["PYTHONWARNINGS"] = "ignore:Blowfish has been deprecated"
210210

211-
if isolated:
212-
self.cache_dir = get_cache_dir(self.project_dir)
211+
self.cache_dir = get_cache_dir(self.project_dir)
212+
213213
self.config = AnsibleConfig(cache_dir=self.cache_dir)
214214

215215
# Add the sys.path to the collection paths if not isolated

test/test_runtime.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ def test_runtime_prepare_ansible_paths_validation() -> None:
143143
runtime._prepare_ansible_paths()
144144

145145

146+
@pytest.mark.filterwarnings("ignore::UserWarning")
146147
@pytest.mark.parametrize(
147148
("folder", "role_name", "isolated"),
148149
(
@@ -652,10 +653,10 @@ def test_upgrade_collection(runtime_tmp: Runtime) -> None:
652653
runtime_tmp.require_collection("community.molecule", "0.1.0")
653654

654655

655-
def test_require_collection_no_cache_dir() -> None:
656+
@pytest.mark.filterwarnings("ignore::UserWarning")
657+
def test_require_collection_not_isolated() -> None:
656658
"""Check require_collection without a cache directory."""
657-
runtime = Runtime()
658-
assert not runtime.cache_dir
659+
runtime = Runtime(isolated=False)
659660
runtime.require_collection("community.molecule", "0.1.0", install=True)
660661

661662

@@ -1018,10 +1019,16 @@ def test_get_galaxy_role_name_invalid() -> None:
10181019
assert _get_galaxy_role_name(galaxy_infos) == ""
10191020

10201021

1022+
@pytest.mark.filterwarnings("ignore::UserWarning")
10211023
def test_runtime_has_playbook() -> None:
10221024
"""Tests has_playbook method."""
10231025
runtime = Runtime(require_module=True)
10241026

1027+
runtime.prepare_environment(
1028+
required_collections={"community.molecule": "0.1.0"},
1029+
install_local=True,
1030+
)
1031+
10251032
assert not runtime.has_playbook("this-does-not-exist.yml")
10261033
# call twice to ensure cache is used:
10271034
assert not runtime.has_playbook("this-does-not-exist.yml")

0 commit comments

Comments
 (0)