From a8ea023d87d0b73e2b6bbc9cea5e4f737d40eb97 Mon Sep 17 00:00:00 2001 From: Daniel Ziegenberg Date: Tue, 23 May 2023 12:57:17 +0200 Subject: [PATCH 1/3] invoke ansible-galaxy with increased verbosity and always log stdout at INFO level This makes ansible-galaxy display important info, when logging level is increased. This helps debugging ansible-lint. Signed-off-by: Daniel Ziegenberg --- src/ansible_compat/runtime.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ansible_compat/runtime.py b/src/ansible_compat/runtime.py index 6ed58e9f..140a9bf7 100644 --- a/src/ansible_compat/runtime.py +++ b/src/ansible_compat/runtime.py @@ -502,7 +502,7 @@ def install_requirements( # noqa: C901 "ansible-galaxy", "role", "install", - "-vr", + "-vvvr", f"{requirement}", ] if self.cache_dir: @@ -516,8 +516,9 @@ def install_requirements( # noqa: C901 _logger.info("Running %s", " ".join(cmd)) result = self.run(cmd, retry=retry) + _logger.info(result.stdout) if result.returncode != 0: - _logger.error(result.stdout) + _logger.error(result.stderr) raise AnsibleCommandError(result) # Run galaxy collection install works on v2 requirements.yml @@ -526,7 +527,7 @@ def install_requirements( # noqa: C901 "ansible-galaxy", "collection", "install", - "-v", + "-vvv", ] if offline: _logger.warning( @@ -548,8 +549,8 @@ def install_requirements( # noqa: C901 retry=retry, env={**os.environ, "ANSIBLE_COLLECTIONS_PATH": ":".join(cpaths)}, ) + _logger.info(result.stdout) if result.returncode != 0: - _logger.error(result.stdout) _logger.error(result.stderr) raise AnsibleCommandError(result) From af6e6ef3789a0c377e29147c146ace14ea6c7957 Mon Sep 17 00:00:00 2001 From: Daniel Ziegenberg Date: Wed, 24 May 2023 13:35:52 +0200 Subject: [PATCH 2/3] control verbosity from the consumer of compat library Signed-off-by: Daniel Ziegenberg --- src/ansible_compat/runtime.py | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/ansible_compat/runtime.py b/src/ansible_compat/runtime.py index 140a9bf7..f5759bc7 100644 --- a/src/ansible_compat/runtime.py +++ b/src/ansible_compat/runtime.py @@ -163,6 +163,7 @@ def __init__( require_module: bool = False, max_retries: int = 0, environ: dict[str, str] | None = None, + verbosity: int = 0, ) -> None: """Initialize Ansible runtime environment. @@ -184,12 +185,17 @@ def __init__( Default is 0, no retries. :param environ: Environment dictionary to use, if undefined ``os.environ`` will be copied and used. + :param verbosity: Verbosity level to use. """ self.project_dir = project_dir or Path.cwd() self.isolated = isolated self.max_retries = max_retries self.environ = environ or os.environ.copy() self.plugins = Plugins(runtime=self) + self.verbosity = verbosity + + self.initialize_logger(level=self.verbosity) + # Reduce noise from paramiko, unless user already defined PYTHONWARNINGS # paramiko/transport.py:236: CryptographyDeprecationWarning: Blowfish has been deprecated # https://github.com/paramiko/paramiko/issues/2038 @@ -230,6 +236,21 @@ def warning( # Monkey patch ansible warning in order to use warnings module. Display.warning = warning + def initialize_logger(self, level: int = 0) -> None: + """Set up the global logging level based on the verbosity number.""" + verbosity_map = { + -2: logging.CRITICAL, + -1: logging.ERROR, + 0: logging.WARNING, + 1: logging.INFO, + 2: logging.DEBUG, + } + # Unknown logging level is treated as DEBUG + logging_level = verbosity_map.get(level, logging.DEBUG) + _logger.setLevel(logging_level) + # Use module-level _logger instance to validate it + _logger.debug("Logging initialized to level %s", logging_level) + def load_collections(self) -> None: """Load collection data.""" self.collections = OrderedDict() @@ -502,9 +523,11 @@ def install_requirements( # noqa: C901 "ansible-galaxy", "role", "install", - "-vvvr", + "-r", f"{requirement}", ] + if self.verbosity > 0: + cmd.extend(["-" + ("v" * self.verbosity)]) if self.cache_dir: cmd.extend(["--roles-path", f"{self.cache_dir}/roles"]) @@ -516,7 +539,7 @@ def install_requirements( # noqa: C901 _logger.info("Running %s", " ".join(cmd)) result = self.run(cmd, retry=retry) - _logger.info(result.stdout) + _logger.debug(result.stdout) if result.returncode != 0: _logger.error(result.stderr) raise AnsibleCommandError(result) @@ -527,8 +550,9 @@ def install_requirements( # noqa: C901 "ansible-galaxy", "collection", "install", - "-vvv", ] + if self.verbosity > 0: + cmd.extend(["-" + ("v" * self.verbosity)]) if offline: _logger.warning( "Skipped installing collection dependencies due to running in offline mode.", @@ -549,7 +573,7 @@ def install_requirements( # noqa: C901 retry=retry, env={**os.environ, "ANSIBLE_COLLECTIONS_PATH": ":".join(cpaths)}, ) - _logger.info(result.stdout) + _logger.debug(result.stdout) if result.returncode != 0: _logger.error(result.stderr) raise AnsibleCommandError(result) From be2f4a6814f4ce1285ee0e7d57298bb337664a88 Mon Sep 17 00:00:00 2001 From: Daniel Ziegenberg Date: Wed, 24 May 2023 17:02:19 +0200 Subject: [PATCH 3/3] fix tests Signed-off-by: Daniel Ziegenberg --- test/test_runtime.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/test_runtime.py b/test/test_runtime.py index 83c87688..78d2f896 100644 --- a/test/test_runtime.py +++ b/test/test_runtime.py @@ -229,10 +229,11 @@ def cwd(path: Path) -> Iterator[None]: os.chdir(old_pwd) -def test_prerun_reqs_v1(caplog: pytest.LogCaptureFixture, runtime: Runtime) -> None: +def test_prerun_reqs_v1(caplog: pytest.LogCaptureFixture) -> None: """Checks that the linter can auto-install requirements v1 when found.""" + runtime = Runtime(verbosity=1) path = Path(__file__).parent.parent / "examples" / "reqs_v1" - with cwd(path), caplog.at_level(logging.INFO): + with cwd(path): runtime.prepare_environment() assert any( msg.startswith("Running ansible-galaxy role install") for msg in caplog.messages @@ -243,12 +244,12 @@ def test_prerun_reqs_v1(caplog: pytest.LogCaptureFixture, runtime: Runtime) -> N ) -def test_prerun_reqs_v2(caplog: pytest.LogCaptureFixture, runtime: Runtime) -> None: +def test_prerun_reqs_v2(caplog: pytest.LogCaptureFixture) -> None: """Checks that the linter can auto-install requirements v2 when found.""" + runtime = Runtime(verbosity=1) path = (Path(__file__).parent.parent / "examples" / "reqs_v2").resolve() with cwd(path): - with caplog.at_level(logging.INFO): - runtime.prepare_environment() + runtime.prepare_environment() assert any( msg.startswith("Running ansible-galaxy role install") for msg in caplog.messages @@ -504,11 +505,10 @@ def test_install_galaxy_role(runtime_tmp: Runtime) -> None: def test_install_galaxy_role_unlink( - runtime_tmp: Runtime, caplog: pytest.LogCaptureFixture, ) -> None: """Test ability to unlink incorrect symlinked roles.""" - caplog.set_level(logging.INFO) + runtime_tmp = Runtime(verbosity=1) runtime_tmp.prepare_environment() pathlib.Path(f"{runtime_tmp.cache_dir}/roles").mkdir(parents=True, exist_ok=True) pathlib.Path(f"{runtime_tmp.cache_dir}/roles/acme.get_rich").symlink_to("/dev/null")