diff --git a/diskimage_builder/elements/package-installs/bin/package-installs-squash b/diskimage_builder/elements/package-installs/bin/package-installs-squash index f5074366..ee39e406 100755 --- a/diskimage_builder/elements/package-installs/bin/package-installs-squash +++ b/diskimage_builder/elements/package-installs/bin/package-installs-squash @@ -128,10 +128,29 @@ def collect_data(data, objs, element_name): (element_name, pkg_name, param)) phase = param.get('phase', 'install.d') installs = ["install"] - if 'uninstall' in param: - installs = ["uninstall"] - if 'build-only' in param: - installs = ["install", "uninstall"] + if 'uninstall' in param or 'build-only' in param: + # We don't add the package to the uninstall list if + # something else has requested we install it without + # removing it. + in_install = any( + map(lambda x: x[0] == pkg_name, data[phase]["install"])) + not_in_uninstall = all( + map(lambda x: x[0] != pkg_name, data[phase]["uninstall"])) + if in_install and not_in_uninstall: + if 'build-only' not in param: + # Just skip further processing as we have no uninstall + # work to do + continue + else: + if 'uninstall' in param: + installs = ["uninstall"] + if 'build-only' in param: + installs = ["install", "uninstall"] + else: + # Remove any uninstallations if we are trying to install + # the package without uninstallation elsewhere. + data[phase]["uninstall"] = [ + x for x in data[phase]["uninstall"] if x[0] != pkg_name] # Filter out incorrect installtypes installtype = param.get('installtype', None) diff --git a/diskimage_builder/elements/package-installs/tests/test_package_squash.py b/diskimage_builder/elements/package-installs/tests/test_package_squash.py index df39ea24..631c987f 100644 --- a/diskimage_builder/elements/package-installs/tests/test_package_squash.py +++ b/diskimage_builder/elements/package-installs/tests/test_package_squash.py @@ -221,3 +221,70 @@ class TestPackageInstall(base.BaseTestCase): } self.assertThat(result, IsMatchingInstallList(expected)) + + def test_install_overrides_uninstall_install_first(self): + '''Test an install overrides uninstall''' + objs = { + 'test_package': '' + } + + result = installs_squash.collect_data( + self.final_dict, objs, 'test_element1') + + expected = { + 'install.d': { + 'install': [('test_package', 'test_element1')] + } + } + + self.assertThat(result, IsMatchingInstallList(expected)) + + objs = { + 'test_package': {'build-only': 'true'} + } + + result = installs_squash.collect_data( + self.final_dict, objs, 'test_element2') + + expected = { + 'install.d': { + 'install': [('test_package', 'test_element1'), + ('test_package', 'test_element2')] + } + } + + self.assertThat(result, IsMatchingInstallList(expected)) + + def test_install_overrides_uninstall_uninstall_first(self): + '''Test an install overrides uninstall''' + objs = { + 'test_package': {'build-only': 'true'} + } + + result = installs_squash.collect_data( + self.final_dict, objs, 'test_element1') + + expected = { + 'install.d': { + 'install': [('test_package', 'test_element1')], + 'uninstall': [('test_package', 'test_element1')] + } + } + + self.assertThat(result, IsMatchingInstallList(expected)) + + objs = { + 'test_package': '' + } + + result = installs_squash.collect_data( + self.final_dict, objs, 'test_element2') + + expected = { + 'install.d': { + 'install': [('test_package', 'test_element1'), + ('test_package', 'test_element2')] + } + } + + self.assertThat(result, IsMatchingInstallList(expected))