From dfe96519b1c14cccf78c24f61aa93905674d75d1 Mon Sep 17 00:00:00 2001 From: Clark Boylan Date: Tue, 19 Mar 2024 14:09:46 -0700 Subject: [PATCH] Replace pkg_resource dep resolution with pip Python 3.12 has more fully excised setuptools and as a result pkg_resources. Since we are using pip to install things we can instead rely on pip to resolve whether or not packages are installed. Do this so that we don't need to explicitly install setuptools where it may not be needed. Change-Id: I8ee189c828914fd648847b5650b5fb2fb255ff17 --- zuul/lib/ansible.py | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/zuul/lib/ansible.py b/zuul/lib/ansible.py index c5b6d9d88d..b8ec6bbb6a 100644 --- a/zuul/lib/ansible.py +++ b/zuul/lib/ansible.py @@ -14,6 +14,7 @@ import concurrent.futures import configparser +import json import logging import os import shutil @@ -235,23 +236,31 @@ class AnsibleManager: result = False try: extra_packages = self._getAnsible(version).extra_packages - python_package_check = \ - "import pkg_resources; pkg_resources.require({})".format( - repr(extra_packages)) - command = [self.getAnsibleCommand(version, 'python'), - '-c', python_package_check] + # Formerly this used pkg_resources which has been deprecated. If + # there is a better way to accomplish this task please change + # this approach. + # Ask pip to resolve a dry run installation to determine if any new + # packages need to be installed. A json doc is emitted to stdout + # including a list of things to install if necessary. + command = [self.getAnsibleCommand(version, 'pip'), 'install', + '--dry-run', '--quiet', '--report', '-'] + command += extra_packages ret = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - # We check manually so that we can log the stdout and stderr - # properly which aren't going to be available if we have - # subprocess.run() check and raise. - if ret.returncode != 0: + to_be_installed = json.loads(ret.stdout)["install"] + # We check manually so that we can log the missing packages + # properly. We also need to check the the JSON output to determine + # if any changes were necessary. + if to_be_installed: self.log.error( 'Ansible version %s installation is missing packages' % version) - self.log.debug("Ansible package check output: %s", ret.stdout) + missing = ["%s %s" % + (x["metadata"]["name"], x["metadata"]["version"]) + for x in to_be_installed] + self.log.debug("These packages are missing: %s", missing) else: result = True except Exception: