File 0023-Adding-dist-upgrade-support-to-zypper-module.patch of Package salt.4202
From 12d9036d77e09c367d53c30fb7a244d94bb4a110 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
<psuarezhernandez@suse.com>
Date: Tue, 18 Oct 2016 14:14:42 +0100
Subject: [PATCH 23/38] Adding 'dist-upgrade' support to zypper module
* Unit tests for zypper upgrade and dist-upgrade
* Refactor: Cleanup and pylint fixes
* Fix in log message
* Adds multiple repositories support to 'fromrepo' parameter
* Improves 'dryrun' outputting. Setting 'novendorchange' as not supported for SLE11
* Unit tests fixes
* Minor pylint fixes
* Disables 'novendorchange' for old SLEs versions
---
salt/modules/zypper.py | 53 +++++++++++++++++++++++++++--
tests/unit/modules/zypper_test.py | 71 +++++++++++++++++++++++++++++++++++++++
2 files changed, 121 insertions(+), 3 deletions(-)
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index 9120ebd..78a6030 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -1049,7 +1049,12 @@ def install(name=None,
return salt.utils.compare_dicts(old, new)
-def upgrade(refresh=True):
+def upgrade(refresh=True,
+ dryrun=False,
+ dist_upgrade=False,
+ fromrepo=None,
+ novendorchange=False,
+ **kwargs): # pylint: disable=unused-argument
'''
.. versionchanged:: 2015.8.12,2016.3.3,Carbon
On minions running systemd>=205, `systemd-run(1)`_ is now used to
@@ -1072,6 +1077,19 @@ def upgrade(refresh=True):
If set to False it depends on zypper if a refresh is
executed.
+ dryrun
+ If set to True, it creates a debug solver log file and then perform
+ a dry-run upgrade (no changes are made). Default: False
+
+ dist_upgrade
+ Perform a system dist-upgrade. Default: False
+
+ fromrepo
+ Specify a list of package repositories to upgrade from. Default: None
+
+ novendorchange
+ If set to True, no allow vendor changes. Default: False
+
Return a dict containing the new package names and versions::
{'<package>': {'old': '<old-version>',
@@ -1082,24 +1100,53 @@ def upgrade(refresh=True):
.. code-block:: bash
salt '*' pkg.upgrade
+ salt '*' pkg.upgrade dist-upgrade=True fromrepo='["MyRepoName"]' novendorchange=True
+ salt '*' pkg.upgrade dist-upgrade=True dryrun=True
'''
ret = {'changes': {},
'result': True,
'comment': '',
}
+ cmd_update = (['dist-upgrade'] if dist_upgrade else ['update']) + ['--auto-agree-with-licenses']
+
if refresh:
refresh_db()
+
+ if dryrun:
+ cmd_update.append('--dry-run')
+
+ if dist_upgrade:
+ if dryrun:
+ # Creates a solver test case for debugging.
+ log.info('Executing debugsolver and performing a dry-run dist-upgrade')
+ __zypper__.noraise.call(*cmd_update + ['--debug-solver'])
+
+ if fromrepo:
+ for repo in fromrepo:
+ cmd_update.extend(['--from', repo])
+ log.info('Targeting repos: {0!r}'.format(fromrepo))
+
+ if novendorchange:
+ # TODO: Grains validation should be moved to Zypper class
+ if __grains__['osrelease_info'][0] > 11:
+ cmd_update.append('--no-allow-vendor-change')
+ log.info('Disabling vendor changes')
+ else:
+ log.warn('Disabling vendor changes is not supported on this Zypper version')
+
old = list_pkgs()
- __zypper__(systemd_scope=_systemd_scope()).noraise.call('update', '--auto-agree-with-licenses')
+ __zypper__.noraise.call(*cmd_update)
if __zypper__.exit_code not in __zypper__.SUCCESS_EXIT_CODES:
ret['result'] = False
- ret['comment'] = (__zypper__.stdout() + os.linesep + __zypper__.stderr()).strip()
else:
__context__.pop('pkg.list_pkgs', None)
new = list_pkgs()
ret['changes'] = salt.utils.compare_dicts(old, new)
+ if dryrun or not ret['result']:
+ ret['comment'] = (__zypper__.stdout() + os.linesep + __zypper__.stderr()).strip()
+
return ret
diff --git a/tests/unit/modules/zypper_test.py b/tests/unit/modules/zypper_test.py
index 3f6a39d..00e746e 100644
--- a/tests/unit/modules/zypper_test.py
+++ b/tests/unit/modules/zypper_test.py
@@ -50,6 +50,7 @@ from salt.modules import zypper
# Globals
zypper.__salt__ = dict()
+zypper.__grains__ = dict()
zypper.__context__ = dict()
zypper.rpm = None
@@ -330,6 +331,76 @@ class ZypperTestCase(TestCase):
self.assertEqual(zypper.latest_version('vim'), '7.4.326-2.62')
@patch('salt.modules.zypper.refresh_db', MagicMock(return_value=True))
+ @patch.dict('salt.modules.zypper.__grains__', {'osrelease_info': [12, 1]})
+ def test_upgrade_success(self):
+ '''
+ Test system upgrade and dist-upgrade success.
+
+ :return:
+ '''
+ with patch('salt.modules.zypper.__zypper__.noraise.call', MagicMock()) as zypper_mock:
+ with patch('salt.modules.zypper.list_pkgs', MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.2"}])):
+ ret = zypper.upgrade()
+ self.assertTrue(ret['result'])
+ self.assertDictEqual(ret['changes'], {"vim": {"old": "1.1", "new": "1.2"}})
+ zypper_mock.assert_any_call('update', '--auto-agree-with-licenses')
+
+ with patch('salt.modules.zypper.list_pkgs', MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.2"}])):
+ ret = zypper.upgrade(dist_upgrade=True)
+ self.assertTrue(ret['result'])
+ self.assertDictEqual(ret['changes'], {"vim": {"old": "1.1", "new": "1.2"}})
+ zypper_mock.assert_any_call('dist-upgrade', '--auto-agree-with-licenses')
+
+ with patch('salt.modules.zypper.list_pkgs', MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}])):
+ ret = zypper.upgrade(dist_upgrade=True, dryrun=True)
+ self.assertTrue(ret['result'])
+ self.assertDictEqual(ret['changes'], {})
+ zypper_mock.assert_any_call('dist-upgrade', '--auto-agree-with-licenses', '--dry-run')
+ zypper_mock.assert_any_call('dist-upgrade', '--auto-agree-with-licenses', '--dry-run', '--debug-solver')
+
+ with patch('salt.modules.zypper.list_pkgs', MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.2"}])):
+ ret = zypper.upgrade(dist_upgrade=True, fromrepo=["Dummy", "Dummy2"], novendorchange=True)
+ self.assertTrue(ret['result'])
+ self.assertDictEqual(ret['changes'], {"vim": {"old": "1.1", "new": "1.2"}})
+ zypper_mock.assert_any_call('dist-upgrade', '--auto-agree-with-licenses', '--from', "Dummy", '--from', 'Dummy2', '--no-allow-vendor-change')
+
+ @patch('salt.modules.zypper.refresh_db', MagicMock(return_value=True))
+ @patch.dict('salt.modules.zypper.__grains__', {'osrelease_info': [12, 1]})
+ def test_upgrade_failure(self):
+ '''
+ Test system upgrade failure.
+
+ :return:
+ '''
+ zypper_out = '''
+Loading repository data...
+Reading installed packages...
+Computing distribution upgrade...
+Use 'zypper repos' to get the list of defined repositories.
+Repository 'DUMMY' not found by its alias, number, or URI.
+'''
+
+ class FailingZypperDummy(object):
+ def __init__(self):
+ self.stdout = MagicMock(return_value=zypper_out)
+ self.stderr = MagicMock(return_value="")
+ self.exit_code = MagicMock(return_value=555)
+ self.noraise = MagicMock()
+ self.SUCCESS_EXIT_CODES = [0]
+
+ def __call__(self, *args, **kwargs):
+ return self
+
+ with patch('salt.modules.zypper.__zypper__', FailingZypperDummy()) as zypper_mock:
+ zypper_mock.noraise.call = MagicMock()
+ with patch('salt.modules.zypper.list_pkgs', MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}])):
+ ret = zypper.upgrade(dist_upgrade=True, fromrepo=["DUMMY"])
+ self.assertFalse(ret['result'])
+ self.assertEqual(ret['comment'], zypper_out.strip())
+ self.assertDictEqual(ret['changes'], {})
+ zypper_mock.noraise.call.assert_called_with('dist-upgrade', '--auto-agree-with-licenses', '--from', 'DUMMY')
+
+ @patch('salt.modules.zypper.refresh_db', MagicMock(return_value=True))
def test_upgrade_available(self):
'''
Test whether or not an upgrade is available for a given package.
--
2.10.2