From 816ead9c767d641e501a566a499c1c02eb61124b Mon Sep 17 00:00:00 2001 From: Jakub Haruda Date: Thu, 22 Oct 2020 19:44:03 +0200 Subject: [PATCH] run-tests: Skip unsupported distributions --- test/checkmeta.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++ test/run-tests | 52 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 test/checkmeta.py diff --git a/test/checkmeta.py b/test/checkmeta.py new file mode 100644 index 0000000..5038e98 --- /dev/null +++ b/test/checkmeta.py @@ -0,0 +1,62 @@ +#!/usr/bin/python3 + +# from __future__ import print_function + +import sys +import yaml + +DISTROS = {"fedora": "Fedora", "rhel": "EL", "centos": "EL"} + + +def distro_to_platform(distro): + """convert distro (ID from os-release(5)) to platform used in role meta""" + return DISTROS.get(distro, distro) + + +def role_supported_versions(metafile, distro): + """return a list of distribution versions that role's metadata claim to support""" + with open(metafile, "r", encoding="utf8") as file: + meta = yaml.safe_load(file) + distinfo = next( + ( + item + for item in meta["galaxy_info"]["platforms"] + if item["name"] == distro_to_platform(distro) + ), + None, + ) + if not distinfo: + return [] + return distinfo["versions"] + + +def version_match(version, meta_version): + # could do more complicated matching, but for now assume that + # meta_version is just a major version (single integer number) or wildcard + return meta_version == "all" or version == str(meta_version) + + +def role_supported(metafile, distro, version): + return any( + ( + version_match(version, meta_version) + for meta_version in role_supported_versions(metafile, distro) + ) + ) + + +if __name__ == "__main__": + USAGE = ( + f"Usage: { sys.argv[0] } /meta/main.yml distribution [majorversion]" + ) + + # sanity-check arguments + if len(sys.argv) not in (3, 4): + print("Invalid arguments.") + print(USAGE) + sys.exit(2) + if len(sys.argv) == 3: + print(role_supported_versions(sys.argv[1], sys.argv[2])) + sys.exit(0) + else: + sys.exit(not role_supported(sys.argv[1], sys.argv[2], sys.argv[3])) diff --git a/test/run-tests b/test/run-tests index 68ec5dd..6a06312 100755 --- a/test/run-tests +++ b/test/run-tests @@ -33,6 +33,7 @@ import yaml # use LooseVersion to handle alphas, betas, other pre-release versions from distutils.version import LooseVersion from distutils.util import strtobool +from checkmeta import role_supported from compose2image import composeurl2images HOSTNAME = socket.gethostname() @@ -353,6 +354,43 @@ class Task: f"in image {self.image['name']}" ) + def is_role_distro_supported(self): + """ + Return True if image is supported. Otherwise False. + """ + distro, version = self.image["name"].split("-") + if version == "x": + image_filename = os.path.basename( + urllib.parse.urlparse(self.get_url()).path + ) + # We expect the first number in the URL image filename to be the major + # version + version = re.search(r"\d+", image_filename).group() + + try: + with checkout_repository( + self.owner, self.repo, f"pull/{self.pull}/head" + ) as repo_tmp_dir: + is_supported = role_supported( + f"{ repo_tmp_dir }/meta/main.yml", distro, version + ) + if is_supported: + logging.debug( + f"The role { self.repo } supports platform " + f"{ self.image['name'] }." + ) + else: + logging.debug( + f"The role { self.repo } does not support platform " + f"{ self.image['name'] }. Skipping." + ) + return is_supported + except Exception: + logging.warning( + "WARNING: Cannot open metafile meta/main.yml. Skipping all images." + ) + return None + def run( self, artifactsdir, private_artifactsdir, cachedir, backend, inventory=None ): @@ -843,6 +881,20 @@ def handle_task(gh, args, config, task, ansible_id, dry_run=False): dry_run = True return + role_supported_state = task.is_role_distro_supported() + if role_supported_state is False: + state = "success" + description = ( + f"The role does not support this platform. Skipping. {description}" + ) + return + elif role_supported_state is None: + state = "failure" + description = ( + f"The role does not contain meta/main.yml file! Skipping. {description}" + ) + return + logging.info("Starting %s", task) timestamp = start_time.strftime("%Y%m%d-%H%M%S")