Hello community, here is the log from the commit of package salt for openSUSE:Factory checked in at 2016-03-07 13:27:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/salt (Old) and /work/SRC/openSUSE:Factory/.salt.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "salt" Changes: -------- --- /work/SRC/openSUSE:Factory/salt/salt.changes 2016-02-24 18:43:08.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.salt.new/salt.changes 2016-03-07 13:28:38.000000000 +0100 @@ -1,0 +2,34 @@ +Fri Mar 4 10:41:52 UTC 2016 - [email protected] + +- Fix the service state / module on SLE11. + Add: + * 0027-make-suse-check-consistent-with-rh_service.patch + * 0028-fix-numerical-check-of-osrelease.patch + +------------------------------------------------------------------- +Fri Mar 4 09:54:00 CET 2016 - [email protected] + +- Prevent rebuilds in OBS by not generating a date as a comment in + a source file + Add: 0026-do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch + +------------------------------------------------------------------- +Fri Feb 26 14:55:14 CET 2016 - [email protected] + +- Add better checking for zypper exit codes and simplify evaluation + of the zypper error messages. + Add: 0024-proper-checking-if-zypper-exit-codes-and-handling-of.patch +- Adapt unit tests + Add: 0025-adapt-tests-to-new-zypper_check_result-output.patch + +------------------------------------------------------------------- +Fri Feb 26 10:42:17 UTC 2016 - [email protected] + +- Add initial pack of Zypper's Unit tests. + Use XML output in list_upgrades. + Bugfix: upgrade_available crashes when only one package specified + Purge is not using "-u" anymore + Add: + * 0023-Initial-Zypper-Unit-Tests-and-bugfixes.patch + +------------------------------------------------------------------- @@ -82,0 +117,3 @@ + Security fixes: + * CVE-2016-1866: Improper handling of clear messages on the + minion remote code execution (boo#965403) New: ---- 0023-Initial-Zypper-Unit-Tests-and-bugfixes.patch 0024-proper-checking-if-zypper-exit-codes-and-handling-of.patch 0025-adapt-tests-to-new-zypper_check_result-output.patch 0026-do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch 0027-make-suse-check-consistent-with-rh_service.patch 0028-fix-numerical-check-of-osrelease.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ salt.spec ++++++ --- /var/tmp/diff_new_pack.ZwMPPP/_old 2016-03-07 13:28:40.000000000 +0100 +++ /var/tmp/diff_new_pack.ZwMPPP/_new 2016-03-07 13:28:40.000000000 +0100 @@ -85,6 +85,17 @@ Patch21: 0021-do-not-change-kwargs-in-refresh-while-checking-a-val.patch # PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/31429 Patch22: 0022-fix-argument-handling-for-pkg.download.patch +# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/31479 +# https://github.com/saltstack/salt/pull/31488 +Patch23: 0023-Initial-Zypper-Unit-Tests-and-bugfixes.patch +# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/31508 +Patch24: 0024-proper-checking-if-zypper-exit-codes-and-handling-of.patch +Patch25: 0025-adapt-tests-to-new-zypper_check_result-output.patch +# PATCH-FIX-OPENSUSE prevent rebuilds in OBS +Patch26: 0026-do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch +# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/31629 +Patch27: 0027-make-suse-check-consistent-with-rh_service.patch +Patch28: 0028-fix-numerical-check-of-osrelease.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: logrotate @@ -449,6 +460,12 @@ %patch20 -p1 %patch21 -p1 %patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 %build python setup.py --salt-transport=both build ++++++ 0023-Initial-Zypper-Unit-Tests-and-bugfixes.patch ++++++ ++++ 673 lines (skipped) ++++++ 0024-proper-checking-if-zypper-exit-codes-and-handling-of.patch ++++++ >From 0372b1ff62a79d0c9f384fe48969d8bae039d5a1 Mon Sep 17 00:00:00 2001 From: Michael Calmer <[email protected]> Date: Thu, 25 Feb 2016 10:20:29 +0100 Subject: [PATCH 24/25] proper checking if zypper exit codes and handling of result messages add function to check zypper exit codes check zypper exit code everywhere add _zypper_check_result() to raise and error or return stdout use _zypper_check_result() remove new lines between zypper command and check result restructure the code a bit --- salt/modules/zypper.py | 144 +++++++++++++++++++++++++++++-------------------- 1 file changed, 85 insertions(+), 59 deletions(-) diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py index ab8bb06..d6628aa 100644 --- a/salt/modules/zypper.py +++ b/salt/modules/zypper.py @@ -26,6 +26,7 @@ except ImportError: # pylint: enable=import-error,redefined-builtin,no-name-in-module from xml.dom import minidom as dom +from xml.parsers.expat import ExpatError # Import salt libs import salt.utils @@ -70,6 +71,53 @@ def _zypper(*opts): return cmd +def _is_zypper_error(retcode): + ''' + Return True in case the exist code indicate a zypper errror. + Otherwise False + ''' + # see man zypper for existing exit codes + return not int(retcode) in [0, 100, 101, 102, 103] + + +def _zypper_check_result(result, xml=False): + ''' + Check the result of a zypper command. In case of an error, it raise + a CommandExecutionError. Otherwise it returns stdout string of the + command. + + result + The result of a zypper command called with cmd.run_all + + xml + Set to True if zypper command was called with --xmlout. + In this case it try to read an error message out of the XML + stream. Default is False. + ''' + if _is_zypper_error(result['retcode']): + msg = list() + if not xml: + msg.append(result['stderr'] and result['stderr'] or "") + else: + try: + doc = dom.parseString(result['stdout']) + except ExpatError as err: + log.error(err) + doc = None + if doc: + msg_nodes = doc.getElementsByTagName('message') + for node in msg_nodes: + if node.getAttribute('type') == 'error': + msg.append(node.childNodes[0].nodeValue) + elif result['stderr'].strip(): + msg.append(result['stderr'].strip()) + + raise CommandExecutionError("zypper command failed: {0}".format( + msg and os.linesep.join(msg) or "Check zypper logs")) + + return result['stdout'] + + def list_upgrades(refresh=True): ''' List all available package upgrades on this system @@ -89,15 +137,7 @@ def list_upgrades(refresh=True): refresh_db() ret = dict() run_data = __salt__['cmd.run_all'](_zypper('-x', 'list-updates'), output_loglevel='trace') - if run_data['retcode'] != 0: - msg = list() - for chnl in ['stderr', 'stdout']: - if run_data.get(chnl, ''): - msg.append(run_data[chnl]) - raise CommandExecutionError(os.linesep.join(msg) or - 'Zypper returned non-zero system exit. See Zypper logs for more details.') - - doc = dom.parseString(run_data['stdout']) + doc = dom.parseString(_zypper_check_result(run_data, xml=True)) for update_node in doc.getElementsByTagName('update'): if update_node.getAttribute('kind') == 'package': ret[update_node.getAttribute('name')] = update_node.getAttribute('edition') @@ -506,7 +546,8 @@ def del_repo(repo): for alias in repos_cfg.sections(): if alias == repo: cmd = _zypper('-x', 'rr', '--loose-auth', '--loose-query', alias) - doc = dom.parseString(__salt__['cmd.run'](cmd, output_loglevel='trace')) + ret = __salt__['cmd.run_all'](cmd, output_loglevel='trace') + doc = dom.parseString(_zypper_check_result(ret, xml=True)) msg = doc.getElementsByTagName('message') if doc.getElementsByTagName('progress') and msg: return { @@ -590,22 +631,8 @@ def mod_repo(repo, **kwargs): 'Repository \'{0}\' already exists as \'{1}\'.'.format(repo, alias)) # Add new repo - doc = None - try: - # Try to parse the output and find the error, - # but this not always working (depends on Zypper version) - doc = dom.parseString(__salt__['cmd.run']( - _zypper('-x', 'ar', url, repo), output_loglevel='trace')) - except Exception: - # No XML out available, but it is still unknown the state of the result. - pass - - if doc: - msg_nodes = doc.getElementsByTagName('message') - if msg_nodes: - msg_node = msg_nodes[0] - if msg_node.getAttribute('type') == 'error': - raise CommandExecutionError(msg_node.childNodes[0].nodeValue) + _zypper_check_result(__salt__['cmd.run_all'](_zypper('-x', 'ar', url, repo), + output_loglevel='trace'), xml=True) # Verify the repository has been added repos_cfg = _get_configured_repos() @@ -641,8 +668,9 @@ def mod_repo(repo, **kwargs): if cmd_opt: cmd_opt.append(repo) - __salt__['cmd.run'](_zypper('-x', 'mr', *cmd_opt), - output_loglevel='trace') + ret = __salt__['cmd.run_all'](_zypper('-x', 'mr', *cmd_opt), + output_loglevel='trace') + _zypper_check_result(ret, xml=True) # If repo nor added neither modified, error should be thrown if not added and not cmd_opt: @@ -666,17 +694,7 @@ def refresh_db(): ''' cmd = _zypper('refresh', '--force') ret = {} - call = __salt__['cmd.run_all'](cmd, output_loglevel='trace') - if call['retcode'] != 0: - comment = '' - if 'stderr' in call: - comment += call['stderr'] - - raise CommandExecutionError( - '{0}'.format(comment) - ) - else: - out = call['stdout'] + out = _zypper_check_result(__salt__['cmd.run_all'](cmd, output_loglevel='trace')) for line in out.splitlines(): if not line: @@ -828,19 +846,18 @@ def install(name=None, cmd = cmd_install + targets[:500] targets = targets[500:] call = __salt__['cmd.run_all'](cmd, output_loglevel='trace', python_shell=False) - if call['retcode'] != 0: - raise CommandExecutionError(call['stderr']) # Fixme: This needs a proper report mechanism. - else: - for line in call['stdout'].splitlines(): - match = re.match(r"^The selected package '([^']+)'.+has lower version", line) - if match: - downgrades.append(match.group(1)) + out = _zypper_check_result(call) + for line in out.splitlines(): + match = re.match(r"^The selected package '([^']+)'.+has lower version", line) + if match: + downgrades.append(match.group(1)) while downgrades: cmd = cmd_install + ['--force'] + downgrades[:500] downgrades = downgrades[500:] - __salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False) + _zypper_check_result(__salt__['cmd.run_all'](cmd, output_loglevel='trace', python_shell=False)) + __context__.pop('pkg.list_pkgs', None) new = list_pkgs() @@ -877,7 +894,7 @@ def upgrade(refresh=True): old = list_pkgs() cmd = _zypper('update', '--auto-agree-with-licenses') call = __salt__['cmd.run_all'](cmd, output_loglevel='trace') - if call['retcode'] != 0: + if _is_zypper_error(call['retcode']): ret['result'] = False if 'stderr' in call: ret['comment'] += call['stderr'] @@ -906,7 +923,8 @@ def _uninstall(name=None, pkgs=None): return {} while targets: - __salt__['cmd.run'](_zypper('remove', *targets[:500]), output_loglevel='trace') + _zypper_check_result(__salt__['cmd.run_all'](_zypper('remove', *targets[:500]), + output_loglevel='trace')) targets = targets[500:] __context__.pop('pkg.list_pkgs', None) @@ -1019,7 +1037,8 @@ def clean_locks(): if not os.path.exists("/etc/zypp/locks"): return out - doc = dom.parseString(__salt__['cmd.run'](_zypper('-x', 'cl'), output_loglevel='trace')) + ret = __salt__['cmd.run_all'](_zypper('-x', 'cl'), output_loglevel='trace') + doc = dom.parseString(_zypper_check_result(ret, xml=True)) for node in doc.getElementsByTagName("message"): text = node.childNodes[0].nodeValue.lower() if text.startswith(LCK): @@ -1057,7 +1076,8 @@ def remove_lock(packages, **kwargs): # pylint: disable=unused-argument missing.append(pkg) if removed: - __salt__['cmd.run'](_zypper('rl', *removed), output_loglevel='trace') + _zypper_check_result(__salt__['cmd.run_all'](_zypper('rl', *removed), + output_loglevel='trace')) return {'removed': len(removed), 'not_found': missing} @@ -1086,7 +1106,8 @@ def add_lock(packages, **kwargs): # pylint: disable=unused-argument added.append(pkg) if added: - __salt__['cmd.run'](_zypper('al', *added), output_loglevel='trace') + _zypper_check_result(__salt__['cmd.run_all'](_zypper('al', *added), + output_loglevel='trace')) return {'added': len(added), 'packages': added} @@ -1218,8 +1239,10 @@ def _get_patterns(installed_only=None): List all known patterns in repos. ''' patterns = {} - doc = dom.parseString(__salt__['cmd.run'](_zypper('--xmlout', 'se', '-t', 'pattern'), - output_loglevel='trace')) + + ret = __salt__['cmd.run_all'](_zypper('--xmlout', 'se', '-t', 'pattern'), + output_loglevel='trace') + doc = dom.parseString(_zypper_check_result(ret, xml=True)) for element in doc.getElementsByTagName('solvable'): installed = element.getAttribute('status') == 'installed' if (installed_only and installed) or not installed_only: @@ -1283,8 +1306,9 @@ def search(criteria, refresh=False): if refresh: refresh_db() - doc = dom.parseString(__salt__['cmd.run'](_zypper('--xmlout', 'se', criteria), - output_loglevel='trace')) + ret = __salt__['cmd.run_all'](_zypper('--xmlout', 'se', criteria), + output_loglevel='trace') + doc = dom.parseString(_zypper_check_result(ret, xml=True)) solvables = doc.getElementsByTagName('solvable') if not solvables: raise CommandExecutionError('No packages found by criteria "{0}".'.format(criteria)) @@ -1343,7 +1367,9 @@ def list_products(all=False, refresh=False): cmd = _zypper('-x', 'products') if not all: cmd.append('-i') - doc = dom.parseString(__salt__['cmd.run'](cmd, output_loglevel='trace')) + + call = __salt__['cmd.run_all'](cmd, output_loglevel='trace') + doc = dom.parseString(_zypper_check_result(call, xml=True)) for prd in doc.getElementsByTagName('product-list')[0].getElementsByTagName('product'): p_nfo = dict() for k_p_nfo, v_p_nfo in prd.attributes.items(): @@ -1390,8 +1416,8 @@ def download(*packages, **kwargs): if refresh: refresh_db() - doc = dom.parseString(__salt__['cmd.run']( - _zypper('-x', 'download', *packages), output_loglevel='trace')) + ret = __salt__['cmd.run_all'](_zypper('-x', 'download', *packages), output_loglevel='trace') + doc = dom.parseString(_zypper_check_result(ret, xml=True)) pkg_ret = {} for dld_result in doc.getElementsByTagName("download-result"): repo = dld_result.getElementsByTagName("repository")[0] -- 2.1.4 ++++++ 0025-adapt-tests-to-new-zypper_check_result-output.patch ++++++ >From de4417cd3de8af72fe2acd2ea22ab7c04327a939 Mon Sep 17 00:00:00 2001 From: Michael Calmer <[email protected]> Date: Fri, 26 Feb 2016 12:05:45 +0100 Subject: [PATCH 25/25] adapt tests to new zypper_check_result() output test _zypper_check_result() use specialized assert functions for tests --- tests/unit/modules/zypper_test.py | 158 ++++++++++++++++++++++++++------------ 1 file changed, 111 insertions(+), 47 deletions(-) diff --git a/tests/unit/modules/zypper_test.py b/tests/unit/modules/zypper_test.py index de964f9..f89d18f 100644 --- a/tests/unit/modules/zypper_test.py +++ b/tests/unit/modules/zypper_test.py @@ -57,12 +57,63 @@ class ZypperTestCase(TestCase): } with patch.dict(zypper.__salt__, {'cmd.run_all': MagicMock(return_value=ref_out)}): upgrades = zypper.list_upgrades(refresh=False) - assert len(upgrades) == 3 + self.assertEqual(len(upgrades), 3) for pkg, version in {'SUSEConnect': '0.2.33-7.1', 'bind-utils': '9.9.6P1-35.1', 'bind-libs': '9.9.6P1-35.1'}.items(): - assert pkg in upgrades - assert upgrades[pkg] == version + self.assertIn(pkg, upgrades) + self.assertEqual(upgrades[pkg], version) + + def test_zypper_check_result(self): + ''' + Test zypper check result function + ''' + cmd_out = { + 'retcode': 1, + 'stdout': '', + 'stderr': 'This is an error' + } + with self.assertRaisesRegexp(CommandExecutionError, "^zypper command failed: This is an error$"): + zypper._zypper_check_result(cmd_out) + + cmd_out = { + 'retcode': 0, + 'stdout': 'result', + 'stderr': '' + } + out = zypper._zypper_check_result(cmd_out) + self.assertEqual(out, "result") + + cmd_out = { + 'retcode': 1, + 'stdout': '', + 'stderr': 'This is an error' + } + with self.assertRaisesRegexp(CommandExecutionError, "^zypper command failed: This is an error$"): + zypper._zypper_check_result(cmd_out, xml=True) + + cmd_out = { + 'retcode': 1, + 'stdout': '', + 'stderr': '' + } + with self.assertRaisesRegexp(CommandExecutionError, "^zypper command failed: Check zypper logs$"): + zypper._zypper_check_result(cmd_out, xml=True) + + cmd_out = { + 'stdout': '''<?xml version='1.0'?> +<stream> + <message type="info">Refreshing service 'container-suseconnect'.</message> + <message type="error">Some handled zypper internal error</message> + <message type="error">Another zypper internal error</message> +</stream> + ''', + 'stderr': '', + 'retcode': 1 + } + with self.assertRaisesRegexp(CommandExecutionError, + "^zypper command failed: Some handled zypper internal error\nAnother zypper internal error$"): + zypper._zypper_check_result(cmd_out, xml=True) def test_list_upgrades_error_handling(self): ''' @@ -71,45 +122,53 @@ class ZypperTestCase(TestCase): ''' # Test handled errors ref_out = { - 'stderr': 'Some handled zypper internal error', + 'stdout': '''<?xml version='1.0'?> +<stream> + <message type="info">Refreshing service 'container-suseconnect'.</message> + <message type="error">Some handled zypper internal error</message> + <message type="error">Another zypper internal error</message> +</stream> + ''', 'retcode': 1 } with patch.dict(zypper.__salt__, {'cmd.run_all': MagicMock(return_value=ref_out)}): - try: + with self.assertRaisesRegexp(CommandExecutionError, + "^zypper command failed: Some handled zypper internal error\nAnother zypper internal error$"): zypper.list_upgrades(refresh=False) - except CommandExecutionError as error: - assert error.message == ref_out['stderr'] # Test unhandled error ref_out = { - 'retcode': 1 + 'retcode': 1, + 'stdout': '', + 'stderr': '' } with patch.dict(zypper.__salt__, {'cmd.run_all': MagicMock(return_value=ref_out)}): - try: + with self.assertRaisesRegexp(CommandExecutionError, '^zypper command failed: Check zypper logs$'): zypper.list_upgrades(refresh=False) - except CommandExecutionError as error: - assert error.message == 'Zypper returned non-zero system exit. See Zypper logs for more details.' def test_list_products(self): ''' List products test. ''' - ref_out = get_test_data('zypper-products.xml') - with patch.dict(zypper.__salt__, {'cmd.run': MagicMock(return_value=ref_out)}): + ref_out = { + 'retcode': 0, + 'stdout': get_test_data('zypper-products.xml') + } + with patch.dict(zypper.__salt__, {'cmd.run_all': MagicMock(return_value=ref_out)}): products = zypper.list_products() - assert len(products) == 5 - assert (['SLES', 'SLES', 'SUSE-Manager-Proxy', 'SUSE-Manager-Server', 'sle-manager-tools-beta'] == + self.assertEqual(len(products), 5) + self.assertEqual(['SLES', 'SLES', 'SUSE-Manager-Proxy', 'SUSE-Manager-Server', 'sle-manager-tools-beta'], sorted([prod['name'] for prod in products])) - assert ('SUSE LLC <https://www.suse.com/>' in [product['vendor'] for product in products]) - assert ([False, False, False, False, True] == + self.assertIn('SUSE LLC <https://www.suse.com/>', [product['vendor'] for product in products]) + self.assertEqual([False, False, False, False, True], sorted([product['isbase'] for product in products])) - assert ([False, False, False, False, True] == + self.assertEqual([False, False, False, False, True], sorted([product['installed'] for product in products])) - assert (['0', '0', '0', '0', '0'] == + self.assertEqual(['0', '0', '0', '0', '0'], sorted([product['release'] for product in products])) - assert ([False, False, False, False, u'sles'] == + self.assertEqual([False, False, False, False, u'sles'], sorted([product['productline'] for product in products])) - assert ([1509408000, 1522454400, 1522454400, 1730332800, 1730332800] == + self.assertEqual([1509408000, 1522454400, 1522454400, 1730332800, 1730332800], sorted([product['eol_t'] for product in products])) def test_refresh_db(self): @@ -168,17 +227,17 @@ class ZypperTestCase(TestCase): with patch.dict(zypper.__salt__, {'lowpkg.info': MagicMock(return_value=run_out)}): installed = zypper.info_installed() # Test overall products length - assert len(installed) == 2 + self.assertEqual(len(installed), 2) # Test translated fields for pkg_name, pkg_info in installed.items(): - assert installed[pkg_name].get('source') == run_out[pkg_name]['source_rpm'] + self.assertEqual(installed[pkg_name].get('source'), run_out[pkg_name]['source_rpm']) # Test keys transition from the lowpkg.info for pn_key, pn_val in run_out['virgo-dummy'].items(): if pn_key == 'source_rpm': continue - assert installed['virgo-dummy'][pn_key] == pn_val + self.assertEqual(installed['virgo-dummy'][pn_key], pn_val) def test_info_available(self): ''' @@ -190,21 +249,21 @@ class ZypperTestCase(TestCase): ref_out = get_test_data('zypper-available.txt') with patch.dict(zypper.__salt__, {'cmd.run_stdout': MagicMock(return_value=ref_out)}): available = zypper.info_available(*test_pkgs, refresh=False) - assert len(available) == 3 + self.assertEqual(len(available), 3) for pkg_name, pkg_info in available.items(): - assert pkg_name in test_pkgs + self.assertIn(pkg_name, test_pkgs) - assert available['emacs']['status'] == 'up-to-date' - assert available['emacs']['installed'] - assert available['emacs']['support level'] == 'Level 3' - assert available['emacs']['vendor'] == 'SUSE LLC <https://www.suse.com/>' - assert available['emacs']['summary'] == 'GNU Emacs Base Package' + self.assertEqual(available['emacs']['status'], 'up-to-date') + self.assertTrue(available['emacs']['installed']) + self.assertEqual(available['emacs']['support level'], 'Level 3') + self.assertEqual(available['emacs']['vendor'], 'SUSE LLC <https://www.suse.com/>') + self.assertEqual(available['emacs']['summary'], 'GNU Emacs Base Package') - assert available['vim']['status'] == 'not installed' - assert not available['vim']['installed'] - assert available['vim']['support level'] == 'Level 3' - assert available['vim']['vendor'] == 'SUSE LLC <https://www.suse.com/>' - assert available['vim']['summary'] == 'Vi IMproved' + self.assertEqual(available['vim']['status'], 'not installed') + self.assertFalse(available['vim']['installed']) + self.assertEqual(available['vim']['support level'], 'Level 3') + self.assertEqual(available['vim']['vendor'], 'SUSE LLC <https://www.suse.com/>') + self.assertEqual(available['vim']['summary'], 'Vi IMproved') @patch('salt.modules.zypper.refresh_db', MagicMock(return_value=True)) def test_latest_version(self): @@ -215,7 +274,7 @@ class ZypperTestCase(TestCase): ''' ref_out = get_test_data('zypper-available.txt') with patch.dict(zypper.__salt__, {'cmd.run_stdout': MagicMock(return_value=ref_out)}): - assert zypper.latest_version('vim') == '7.4.326-2.62' + self.assertEqual(zypper.latest_version('vim'), '7.4.326-2.62') @patch('salt.modules.zypper.refresh_db', MagicMock(return_value=True)) def test_upgrade_available(self): @@ -227,8 +286,8 @@ class ZypperTestCase(TestCase): ref_out = get_test_data('zypper-available.txt') with patch.dict(zypper.__salt__, {'cmd.run_stdout': MagicMock(return_value=ref_out)}): for pkg_name in ['emacs', 'python']: - assert not zypper.upgrade_available(pkg_name) - assert zypper.upgrade_available('vim') + self.assertFalse(zypper.upgrade_available(pkg_name)) + self.assertTrue(zypper.upgrade_available('vim')) @patch('salt.modules.zypper.HAS_RPM', True) def test_version_cmp_rpm(self): @@ -239,7 +298,7 @@ class ZypperTestCase(TestCase): ''' with patch('salt.modules.zypper.rpm', MagicMock(return_value=MagicMock)): with patch('salt.modules.zypper.rpm.labelCompare', MagicMock(return_value=0)): - assert 0 == zypper.version_cmp('1', '2') # mock returns 0, which means RPM was called + self.assertEqual(0, zypper.version_cmp('1', '2')) # mock returns 0, which means RPM was called @patch('salt.modules.zypper.HAS_RPM', False) def test_version_cmp_fallback(self): @@ -250,7 +309,7 @@ class ZypperTestCase(TestCase): ''' with patch('salt.modules.zypper.rpm', MagicMock(return_value=MagicMock)): with patch('salt.modules.zypper.rpm.labelCompare', MagicMock(return_value=0)): - assert -1 == zypper.version_cmp('1', '2') # mock returns -1, a python implementation was called + self.assertEqual(-1, zypper.version_cmp('1', '2')) # mock returns -1, a python implementation was called def test_list_pkgs(self): ''' @@ -281,8 +340,8 @@ class ZypperTestCase(TestCase): 'susemanager-build-keys-web': '12.0-5.1.develHead', 'apache-commons-cli': '1.2-1.233', 'jose4j': '0.4.4-2.1.develHead'}.items(): - assert pkgs.get(pkg_name) - assert pkgs[pkg_name] == pkg_version + self.assertTrue(pkgs.get(pkg_name)) + self.assertEqual(pkgs[pkg_name], pkg_version) def test_remove_purge(self): ''' @@ -307,16 +366,21 @@ class ZypperTestCase(TestCase): return pkgs parsed_targets = [{'vim': None, 'pico': None}, None] + cmd_out = { + 'retcode': 0, + 'stdout': '', + 'stderr': '' + } - with patch.dict(zypper.__salt__, {'cmd.run': MagicMock(return_value=False)}): + with patch.dict(zypper.__salt__, {'cmd.run_all': MagicMock(return_value=cmd_out)}): with patch.dict(zypper.__salt__, {'pkg_resource.parse_targets': MagicMock(return_value=parsed_targets)}): with patch.dict(zypper.__salt__, {'pkg_resource.stringify': MagicMock()}): with patch('salt.modules.zypper.list_pkgs', ListPackages()): diff = zypper.remove(name='vim,pico') for pkg_name in ['vim', 'pico']: - assert diff.get(pkg_name) - assert diff[pkg_name]['old'] - assert not diff[pkg_name]['new'] + self.assertTrue(diff.get(pkg_name)) + self.assertTrue(diff[pkg_name]['old']) + self.assertFalse(diff[pkg_name]['new']) if __name__ == '__main__': -- 2.1.4 ++++++ 0026-do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch ++++++ >From 80784a70e90d16c5d8290fcc6bf8a0f4ec657ec0 Mon Sep 17 00:00:00 2001 From: Michael Calmer <[email protected]> Date: Fri, 4 Mar 2016 09:51:22 +0100 Subject: [PATCH 26/26] do not generate a date in a comment to prevent rebuilds (bsc#969407) --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 8caa45e..dd76c64 100755 --- a/setup.py +++ b/setup.py @@ -600,8 +600,7 @@ class Clean(clean): INSTALL_VERSION_TEMPLATE = '''\ -# This file was auto-generated by salt's setup on \ -{date:%A, %d %B %Y @ %H:%m:%S UTC}. +# This file was auto-generated by salt's setup from salt.version import SaltStackVersion -- 2.1.4 ++++++ 0027-make-suse-check-consistent-with-rh_service.patch ++++++ >From 9b8d6cbb72cd6537016a9d4da73bd3127b951845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20R=C3=BCckert?= <[email protected]> Date: Wed, 2 Mar 2016 17:29:23 +0100 Subject: [PATCH] make the suse check consistent with rh_service.py --- salt/modules/service.py | 1 + 1 file changed, 1 insertion(+) diff --git a/salt/modules/service.py b/salt/modules/service.py index 05db855..7aacedd 100644 --- a/salt/modules/service.py +++ b/salt/modules/service.py @@ -37,6 +37,7 @@ def __virtual__(): 'Arch ARM', 'ALT', 'SUSE Enterprise Server', + 'SUSE', 'OEL', 'Linaro', 'elementary OS', ++++++ 0028-fix-numerical-check-of-osrelease.patch ++++++ >From c0c8a77242cac5565febc9b08aeda7328d13e92f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20R=C3=BCckert?= <[email protected]> Date: Wed, 2 Mar 2016 17:29:54 +0100 Subject: [PATCH] Fix numerical check of osrelease After making the version check numerical in 9975508 it no longer matched SLES 11 properly to use the rh_service module as '11.4 > 11' evaluates to true. Without using the rh_service module, not all methods are implemented to use the service state on sle11. --- salt/modules/rh_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/modules/rh_service.py b/salt/modules/rh_service.py index c425cde..910a75d 100644 --- a/salt/modules/rh_service.py +++ b/salt/modules/rh_service.py @@ -66,8 +66,8 @@ def __virtual__(): return (False, 'Cannot load rh_service module: ' 'osrelease grain, {0}, not a float,'.format(osrelease)) if __grains__['os'] == 'SUSE': - if osrelease > 11: - return (False, 'Cannot load rh_service module on SUSE >= 11') + if osrelease >= 12: + return (False, 'Cannot load rh_service module on SUSE >= 12') if __grains__['os'] == 'Fedora': if osrelease > 15: return (False, 'Cannot load rh_service module on Fedora >= 15')
