diff --git a/src/pylorax/api/compose.py b/src/pylorax/api/compose.py index 07522e07..95e0907f 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 9e5c0998..81f76971 100644 --- a/src/pylorax/api/v0.py +++ b/src/pylorax/api/v0.py @@ -1832,12 +1832,9 @@ def v0_api(api): @api.route("/api/v0/compose/types") @crossdomain(origin="*") def v0_compose_types(): - """Return the list of enabled output types - - (only enabled types are returned) - """ + """Return the list of output types and their enabled/disabled state""" 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)]) @api.route("/api/v0/compose/queue") @crossdomain(origin="*") diff --git a/tests/pylorax/test_compose.py b/tests/pylorax/test_compose.py index 4948c79a..442c3305 100644 --- a/tests/pylorax/test_compose.py +++ b/tests/pylorax/test_compose.py @@ -15,6 +15,7 @@ # along with this program. If not, see . # from io import StringIO +import os import shutil import tempfile import unittest @@ -742,7 +743,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() @@ -835,3 +836,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 e53789b7..34615496 100644 --- a/tests/pylorax/test_server.py +++ b/tests/pylorax/test_server.py @@ -858,6 +858,10 @@ class ServerTestCase(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",