From e365e476afc3aa7f3c7b2db9bc92344280e1c432 Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Mon, 28 Oct 2019 10:56:47 -0700 Subject: [PATCH] Disable some compose types on other architectures The 'enabled' field in the /compose/types output now reflects whether or not the type is supported on the current architecture. Disabled types are not allowed to be built, and will raise an error like: Compose type 'alibaba' is disabled on this architecture --- src/pylorax/api/compose.py | 37 +++++++++++++++++++++++++++++------ src/pylorax/api/v0.py | 2 +- tests/pylorax/test_compose.py | 10 +++++++++- tests/pylorax/test_server.py | 4 ++++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/pylorax/api/compose.py b/src/pylorax/api/compose.py index af8e5377..dd20a882 100644 --- a/src/pylorax/api/compose.py +++ b/src/pylorax/api/compose.py @@ -68,7 +68,10 @@ def test_templates(dbo, share_dir): Return a list of templates and errors encountered or an empty list """ template_errors = [] - for compose_type in compose_types(share_dir): + for compose_type, enabled in compose_types(share_dir): + if not enabled: + continue + # Read the kickstart template for this type ks_template_path = joinpaths(share_dir, "composer", compose_type) + ".ks" ks_template = open(ks_template_path, "r").read() @@ -688,9 +691,12 @@ def start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_m share_dir = cfg.get("composer", "share_dir") lib_dir = cfg.get("composer", "lib_dir") - # Make sure compose_type is valid - if compose_type not in compose_types(share_dir): - raise RuntimeError("Invalid compose type (%s), must be one of %s" % (compose_type, compose_types(share_dir))) + # Make sure compose_type is valid, only allow enabled types + type_enabled = dict(compose_types(share_dir)).get(compose_type) + if type_enabled is None: + raise RuntimeError("Invalid compose type (%s), must be one of %s" % (compose_type, [t for t, e in compose_types(share_dir)])) + if not type_enabled: + raise RuntimeError("Compose type '%s' is disabled on this architecture" % compose_type) # Some image types (live-iso) need extra packages for composer to execute the output template with dnflock.lock: @@ -859,11 +865,30 @@ def start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_m # Supported output types def compose_types(share_dir): - r""" Returns a list of the supported output types + r""" Returns a list of tuples of the supported output types, and their state The output types come from the kickstart names in /usr/share/lorax/composer/\*ks + + If they are disabled on the current arch their state is False. If enabled, it is True. + eg. [("alibaba", False), ("ext4-filesystem", True), ...] """ - return sorted([os.path.basename(ks)[:-3] for ks in glob(joinpaths(share_dir, "composer/*.ks"))]) + # These are compose types that are not supported on an architecture. eg. hyper-v on s390 + # If it is not listed, it is allowed + disable_map = { + "arm": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "armhfp": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "aarch64": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "ppc": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "ppc64": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "ppc64le": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "s390": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "s390x": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + } + + all_types = sorted([os.path.basename(ks)[:-3] for ks in glob(joinpaths(share_dir, "composer/*.ks"))]) + arch_disabled = disable_map.get(os.uname().machine, []) + + return [(t, t not in arch_disabled) for t in all_types] def compose_args(compose_type): """ Returns the settings to pass to novirt_install for the compose type diff --git a/src/pylorax/api/v0.py b/src/pylorax/api/v0.py index 7fb61aa4..f7d0b317 100644 --- a/src/pylorax/api/v0.py +++ b/src/pylorax/api/v0.py @@ -1495,7 +1495,7 @@ def v0_compose_types(): } """ share_dir = api.config["COMPOSER_CFG"].get("composer", "share_dir") - return jsonify(types=[{"name": k, "enabled": True} for k in compose_types(share_dir)]) + return jsonify(types=[{"name": t, "enabled": e} for t, e in compose_types(share_dir)]) @v0_api.route("/compose/queue") def v0_compose_queue(): diff --git a/tests/pylorax/test_compose.py b/tests/pylorax/test_compose.py index d58db0ce..de697ed7 100644 --- a/tests/pylorax/test_compose.py +++ b/tests/pylorax/test_compose.py @@ -744,7 +744,7 @@ disabled = ["postfix", "telnetd"] # Test against all of the available templates share_dir = "./share/" errors = [] - for compose_type in compose_types(share_dir): + for compose_type, _enabled in compose_types(share_dir): # Read the kickstart template for this type ks_template_path = joinpaths(share_dir, "composer", compose_type) + ".ks" ks_template = open(ks_template_path, "r").read() @@ -837,3 +837,11 @@ class ExtraPkgsTest(unittest.TestCase): """Test that non-live doesn't parse live-install.tmpl""" extra_pkgs = get_extra_pkgs(self.dbo, "./share/", "qcow2") self.assertEqual(extra_pkgs, []) + +class ComposeTypesTest(unittest.TestCase): + def test_compose_types(self): + types = compose_types("./share/") + self.assertTrue(("qcow2", True) in types) + + if os.uname().machine != 'x86_64': + self.assertTrue(("alibaba", False) in types) diff --git a/tests/pylorax/test_server.py b/tests/pylorax/test_server.py index 7b94433a..02dd97d7 100644 --- a/tests/pylorax/test_server.py +++ b/tests/pylorax/test_server.py @@ -960,6 +960,10 @@ class ServerAPIV0TestCase(unittest.TestCase): self.assertNotEqual(data, None) self.assertEqual({"name": "tar", "enabled": True} in data["types"], True) + # All of the non-x86 compose types disable alibaba + if os.uname().machine != 'x86_64': + self.assertEqual({"name": "alibaba", "enabled": False} in data["types"], True) + def test_compose_02_bad_type(self): """Test that using an unsupported image type failes""" test_compose = {"blueprint_name": "example-glusterfs",