From 0b94bef0d79659a81e0a093cb546b3adc00ffed6 Mon Sep 17 00:00:00 2001 From: David Ames Date: Wed, 19 Sep 2018 06:56:07 +0000 Subject: [PATCH 1/2] Set APT to non-interactive on series upgrade A number of packages were requiring interaction on upgrade even with do-release-upgrade -f DistUpgradeViewNonInteractive. By setting DPkg options in apt.conf upgraded packages do the right thing. Set 'DPkg::options { "--force-confdef"; };' on hosts being upgraded. --- .../utilities/test_zaza_utilities_generic.py | 15 +++++++++++++-- zaza/utilities/generic.py | 19 ++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/unit_tests/utilities/test_zaza_utilities_generic.py b/unit_tests/utilities/test_zaza_utilities_generic.py index f44bf74..4f06c39 100644 --- a/unit_tests/utilities/test_zaza_utilities_generic.py +++ b/unit_tests/utilities/test_zaza_utilities_generic.py @@ -169,8 +169,8 @@ class TestGenericUtils(ut_utils.BaseTestCase): _unit = "app/2" generic_utils.do_release_upgrade(_unit) self.subprocess.check_call.assert_called_once_with( - ['juju', 'ssh', _unit, 'sudo', 'do-release-upgrade', - '-f', 'DistUpgradeViewNonInteractive']) + ['juju', 'ssh', _unit, 'sudo', 'DEBIAN_FRONTEND=noninteractive', + 'do-release-upgrade', '-f', 'DistUpgradeViewNonInteractive']) def test_wrap_do_release_upgrade(self): self.patch_object(generic_utils, "do_release_upgrade") @@ -351,3 +351,14 @@ class TestGenericUtils(ut_utils.BaseTestCase): workaround_script=_workaround_script, files=_files) self.run_action.assert_not_called() self.series_upgrade.assert_has_calls(_series_upgrade_calls) + + def test_set_dpkg_non_interactive_on_unit(self): + self.patch_object(generic_utils, "model") + _unit_name = "app/1" + generic_utils.set_dpkg_non_interactive_on_unit(_unit_name) + self.model.run_on_unit.assert_called_with( + "app/1", + 'grep \'DPkg::options { "--force-confdef"; };\' ' + '/etc/apt/apt.conf.d/50unattended-upgrades || ' + 'echo \'DPkg::options { "--force-confdef"; };\' >> ' + '/etc/apt/apt.conf.d/50unattended-upgrades') diff --git a/zaza/utilities/generic.py b/zaza/utilities/generic.py index b5a549c..260334a 100644 --- a/zaza/utilities/generic.py +++ b/zaza/utilities/generic.py @@ -269,6 +269,7 @@ def series_upgrade(unit_name, machine_num, """ logging.info("Series upgrade {}".format(unit_name)) application = unit_name.split('/')[0] + set_dpkg_non_interactive_on_unit(unit_name) logging.info("Prepare series upgrade on {}".format(machine_num)) model.prepare_series_upgrade(machine_num, to_series=to_series) logging.info("Watiing for workload status 'unknown' on {}" @@ -390,7 +391,7 @@ def do_release_upgrade(unit_name): logging.info('Upgrading ' + unit_name) # NOTE: It is necessary to run this via juju ssh rather than juju run due # to timeout restrictions and error handling. - cmd = ['juju', 'ssh', unit_name, 'sudo', + cmd = ['juju', 'ssh', unit_name, 'sudo', 'DEBIAN_FRONTEND=noninteractive', 'do-release-upgrade', '-f', 'DistUpgradeViewNonInteractive'] try: subprocess.check_call(cmd) @@ -415,3 +416,19 @@ def reboot(unit_name): except subprocess.CalledProcessError as e: logging.info(e) pass + + +def set_dpkg_non_interactive_on_unit( + unit_name, apt_conf_d="/etc/apt/apt.conf.d/50unattended-upgrades"): + """Set dpkg options on unit. + + :param unit_name: Unit Name + :type unit_name: str + :param apt_conf_d: Apt.conf file to update + :type apt_conf_d: str + """ + DPKG_NON_INTERACTIVE = 'DPkg::options { "--force-confdef"; };' + # Check if the option exists. If not, add it to the apt.conf.d file + cmd = ("grep '{option}' {file_name} || echo '{option}' >> {file_name}" + .format(option=DPKG_NON_INTERACTIVE, file_name=apt_conf_d)) + model.run_on_unit(unit_name, cmd) From b1320cefeebd53fdf0b0ed0e434df1dfa698c18d Mon Sep 17 00:00:00 2001 From: David Ames Date: Wed, 19 Sep 2018 07:40:28 +0000 Subject: [PATCH 2/2] Workaround script and files no longer necessary By setting the DPkg options for non-interactive the workaround script and files are no longer necessary for the test automation. --- zaza/charm_tests/series_upgrade/tests.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/zaza/charm_tests/series_upgrade/tests.py b/zaza/charm_tests/series_upgrade/tests.py index 3e63d1b..424efd8 100644 --- a/zaza/charm_tests/series_upgrade/tests.py +++ b/zaza/charm_tests/series_upgrade/tests.py @@ -39,10 +39,7 @@ class SeriesUpgradeTest(unittest.TestCase): cls.lts.setUpClass() cls.from_series = None cls.to_series = None - # While there are packaging upgrade bugs we need to be cheeky and - # workaround by using the new package's version of files - cls.workaround_script = "/home/ubuntu/package-workarounds.sh" - cls.src_workaround_script = os.path.basename(cls.workaround_script) + cls.workaround_script = None cls.files = [] def test_100_validate_pre_series_upgrade_cloud(self): @@ -103,8 +100,6 @@ class TrustyXenialSeriesUpgrade(SeriesUpgradeTest): super(TrustyXenialSeriesUpgrade, cls).setUpClass() cls.from_series = "trusty" cls.to_series = "xenial" - cls.files = [cls.src_workaround_script, - 'corosync', 'corosync.conf'] class XenialBionicSeriesUpgrade(SeriesUpgradeTest): @@ -116,8 +111,6 @@ class XenialBionicSeriesUpgrade(SeriesUpgradeTest): super(XenialBionicSeriesUpgrade, cls).setUpClass() cls.from_series = "xenial" cls.to_series = "bionic" - cls.files = [cls.src_workaround_script, - 'corosync', 'corosync.conf', 'haproxy.cfg'] if __name__ == "__main__":