From 9ce4d6f2a0ae5e7d099b7ecac9990ef2d5c0fc89f40d7454bd3a17ecd7b1cb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= Date: Fri, 26 Apr 2019 10:09:06 +0000 Subject: [PATCH] osc copypac from project:systemsmanagement:saltstack:testing package:salt revision:258 OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=133 --- _lastrevision | 2 +- ...ce_ping_timeout-and-batch_presence_p.patch | 46 ++++ ....volume_infos-and-virt.volume_delete.patch | 84 +++--- ...in-parallel-to-avoid-blockings-bsc-1.patch | 77 ++++++ ...zypper-with-more-than-one-no-refresh.patch | 14 +- fix-async-batch-race-conditions.patch | 253 ++++++++++++++++++ mount-fix-extra-t-parameter.patch | 30 +++ salt.changes | 23 ++ salt.spec | 25 +- 9 files changed, 508 insertions(+), 46 deletions(-) create mode 100644 add-batch_presence_ping_timeout-and-batch_presence_p.patch create mode 100644 calculate-fqdns-in-parallel-to-avoid-blockings-bsc-1.patch create mode 100644 fix-async-batch-race-conditions.patch create mode 100644 mount-fix-extra-t-parameter.patch diff --git a/_lastrevision b/_lastrevision index 4543d1d..80c5c4f 100644 --- a/_lastrevision +++ b/_lastrevision @@ -1 +1 @@ -65afa65b0d69f90c1cd716474cdddcdc98751274 \ No newline at end of file +8bef2df02d5c189cef341f81679fda05b6c02930 \ No newline at end of file diff --git a/add-batch_presence_ping_timeout-and-batch_presence_p.patch b/add-batch_presence_ping_timeout-and-batch_presence_p.patch new file mode 100644 index 0000000..4ac8fc8 --- /dev/null +++ b/add-batch_presence_ping_timeout-and-batch_presence_p.patch @@ -0,0 +1,46 @@ +From 902a3527415807448be0aa28a651374a189d102c Mon Sep 17 00:00:00 2001 +From: Marcelo Chiaradia +Date: Thu, 4 Apr 2019 13:57:38 +0200 +Subject: [PATCH] Add 'batch_presence_ping_timeout' and + 'batch_presence_ping_gather_job_timeout' parameters for synchronous batching + +--- + salt/cli/batch.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/salt/cli/batch.py b/salt/cli/batch.py +index 4bd07f584a..ce239215cb 100644 +--- a/salt/cli/batch.py ++++ b/salt/cli/batch.py +@@ -83,6 +83,9 @@ def batch_get_opts( + if key not in opts: + opts[key] = val + ++ opts['batch_presence_ping_timeout'] = kwargs.get('batch_presence_ping_timeout', opts['timeout']) ++ opts['batch_presence_ping_gather_job_timeout'] = kwargs.get('batch_presence_ping_gather_job_timeout', opts['gather_job_timeout']) ++ + return opts + + +@@ -119,7 +122,7 @@ class Batch(object): + args = [self.opts['tgt'], + 'test.ping', + [], +- self.opts['timeout'], ++ self.opts.get('batch_presence_ping_timeout', self.opts['timeout']), + ] + + selected_target_option = self.opts.get('selected_target_option', None) +@@ -130,7 +133,7 @@ class Batch(object): + + self.pub_kwargs['yield_pub_data'] = True + ping_gen = self.local.cmd_iter(*args, +- gather_job_timeout=self.opts['gather_job_timeout'], ++ gather_job_timeout=self.opts.get('batch_presence_ping_gather_job_timeout', self.opts['gather_job_timeout']), + **self.pub_kwargs) + + # Broadcast to targets +-- +2.20.1 + + diff --git a/add-virt.volume_infos-and-virt.volume_delete.patch b/add-virt.volume_infos-and-virt.volume_delete.patch index c2d5622..a583d2e 100644 --- a/add-virt.volume_infos-and-virt.volume_delete.patch +++ b/add-virt.volume_infos-and-virt.volume_delete.patch @@ -1,4 +1,4 @@ -From 2536ee56bd0060c024994f97388f9975ccbe1ee1 Mon Sep 17 00:00:00 2001 +From 5e202207d02d2bf4860cc5487ed19f9d835993d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= Date: Fri, 15 Feb 2019 17:28:00 +0100 Subject: [PATCH] Add virt.volume_infos() and virt.volume_delete() @@ -11,15 +11,15 @@ names of the virtual machines using the volumes of file type. virt.volume_delete() allows removing a given volume. --- - salt/modules/virt.py | 113 ++++++++++++++++++++ - tests/unit/modules/test_virt.py | 184 ++++++++++++++++++++++++++++++++ - 2 files changed, 297 insertions(+) + salt/modules/virt.py | 126 +++++++++++++++++++++ + tests/unit/modules/test_virt.py | 195 ++++++++++++++++++++++++++++++++ + 2 files changed, 321 insertions(+) diff --git a/salt/modules/virt.py b/salt/modules/virt.py -index 0921122a8a..4a301f289c 100644 +index 0921122a8a..17039444c4 100644 --- a/salt/modules/virt.py +++ b/salt/modules/virt.py -@@ -4988,3 +4988,116 @@ def pool_list_volumes(name, **kwargs): +@@ -4988,3 +4988,129 @@ def pool_list_volumes(name, **kwargs): return pool.listVolumes() finally: conn.close() @@ -34,6 +34,19 @@ index 0921122a8a..4a301f289c 100644 + return pool_obj.storageVolLookupByName(vol) + + ++def _is_valid_volume(vol): ++ ''' ++ Checks whether a volume is valid for further use since those may have disappeared since ++ the last pool refresh. ++ ''' ++ try: ++ # Getting info on an invalid volume raises error ++ vol.info() ++ return True ++ except libvirt.libvirtError as err: ++ return False ++ ++ +def _get_all_volumes_paths(conn): + ''' + Extract the path and backing stores path of all volumes. @@ -42,17 +55,17 @@ index 0921122a8a..4a301f289c 100644 + ''' + volumes = [vol for l in [obj.listAllVolumes() for obj in conn.listAllStoragePools()] for vol in l] + return {vol.path(): [path.text for path in ElementTree.fromstring(vol.XMLDesc()).findall('.//backingStore/path')] -+ for vol in volumes} ++ for vol in volumes if _is_valid_volume(vol)} + + -+def volume_infos(pool, volume, **kwargs): ++def volume_infos(pool=None, volume=None, **kwargs): + ''' + Provide details on a storage volume. If no volume name is provided, the infos + all the volumes contained in the pool are provided. If no pool is provided, + the infos of the volumes of all pools are output. + -+ :param pool: libvirt storage pool name -+ :param volume: name of the volume to get infos from ++ :param pool: libvirt storage pool name (default: ``None``) ++ :param volume: name of the volume to get infos from (default: ``None``) + :param connection: libvirt connection URI, overriding defaults + :param username: username to connect with, overriding defaults + :param password: password to connect with, overriding defaults @@ -102,7 +115,7 @@ index 0921122a8a..4a301f289c 100644 + pools = [obj for obj in conn.listAllStoragePools() if pool is None or obj.name() == pool] + vols = {pool_obj.name(): {vol.name(): _volume_extract_infos(vol) + for vol in pool_obj.listAllVolumes() -+ if volume is None or vol.name() == volume} ++ if (volume is None or vol.name() == volume) and _is_valid_volume(vol)} + for pool_obj in pools} + return {pool_name: volumes for (pool_name, volumes) in vols.items() if volumes} + except libvirt.libvirtError as err: @@ -137,10 +150,10 @@ index 0921122a8a..4a301f289c 100644 + finally: + conn.close() diff --git a/tests/unit/modules/test_virt.py b/tests/unit/modules/test_virt.py -index bd34962a6a..55005f1d04 100644 +index bd34962a6a..14e51e1e2a 100644 --- a/tests/unit/modules/test_virt.py +++ b/tests/unit/modules/test_virt.py -@@ -2698,3 +2698,187 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin): +@@ -2698,3 +2698,198 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin): self.mock_conn.storagePoolLookupByName.return_value = mock_pool # pylint: enable=no-member self.assertEqual(names, virt.pool_list_volumes('default')) @@ -203,6 +216,13 @@ index bd34962a6a..55005f1d04 100644 + 'name': 'pool1', + 'volumes': [ + { ++ 'key': '/key/of/vol0bad', ++ 'name': 'vol0bad', ++ 'path': '/path/to/vol0bad.qcow2', ++ 'info': None, ++ 'backingStore': None ++ }, ++ { + 'key': '/key/of/vol1', + 'name': 'vol1', + 'path': '/path/to/vol1.qcow2', @@ -230,23 +250,27 @@ index bd34962a6a..55005f1d04 100644 + mock_volume.name.return_value = vol_data['name'] + mock_volume.key.return_value = vol_data['key'] + mock_volume.path.return_value = '/path/to/{0}.qcow2'.format(vol_data['name']) -+ mock_volume.info.return_value = vol_data['info'] -+ backing_store = ''' -+ -+ qcow2 -+ {0} -+ -+ '''.format(vol_data['backingStore']) if vol_data['backingStore'] else '' -+ mock_volume.XMLDesc.return_value = ''' -+ -+ {0} -+ -+ qcow2 -+ /path/to/{0}.qcow2 -+ -+ {1} -+ -+ '''.format(vol_data['name'], backing_store) ++ if vol_data['info']: ++ mock_volume.info.return_value = vol_data['info'] ++ backing_store = ''' ++ ++ qcow2 ++ {0} ++ ++ '''.format(vol_data['backingStore']) if vol_data['backingStore'] else '' ++ mock_volume.XMLDesc.return_value = ''' ++ ++ {0} ++ ++ qcow2 ++ /path/to/{0}.qcow2 ++ ++ {1} ++ ++ '''.format(vol_data['name'], backing_store) ++ else: ++ mock_volume.info.side_effect = self.mock_libvirt.libvirtError('No such volume') ++ mock_volume.XMLDesc.side_effect = self.mock_libvirt.libvirtError('No such volume') + mock_volumes.append(mock_volume) + # pylint: enable=no-member + mock_pool.listAllVolumes.return_value = mock_volumes # pylint: disable=no-member diff --git a/calculate-fqdns-in-parallel-to-avoid-blockings-bsc-1.patch b/calculate-fqdns-in-parallel-to-avoid-blockings-bsc-1.patch new file mode 100644 index 0000000..685c77b --- /dev/null +++ b/calculate-fqdns-in-parallel-to-avoid-blockings-bsc-1.patch @@ -0,0 +1,77 @@ +From 722b9395a6489da7626e6a388c78bf8e8812190e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= + +Date: Fri, 12 Apr 2019 16:47:03 +0100 +Subject: [PATCH] Calculate FQDNs in parallel to avoid blockings (bsc#1129079) + +Fix pylint issue +--- + salt/grains/core.py | 31 ++++++++++++++++++++++++++----- + 1 file changed, 26 insertions(+), 5 deletions(-) + +diff --git a/salt/grains/core.py b/salt/grains/core.py +index 05a9d5035d..796458939d 100644 +--- a/salt/grains/core.py ++++ b/salt/grains/core.py +@@ -20,11 +20,14 @@ import platform + import logging + import locale + import uuid ++import time + import zlib + from errno import EACCES, EPERM + import datetime + import warnings + ++from multiprocessing.dummy import Pool as ThreadPool ++ + # pylint: disable=import-error + try: + import dateutil.tz +@@ -2200,13 +2203,10 @@ def fqdns(): + grains = {} + fqdns = set() + +- addresses = salt.utils.network.ip_addrs(include_loopback=False, interface_data=_get_interfaces()) +- addresses.extend(salt.utils.network.ip_addrs6(include_loopback=False, interface_data=_get_interfaces())) +- err_message = 'Exception during resolving address: %s' +- for ip in addresses: ++ def _lookup_fqdn(ip): + try: + name, aliaslist, addresslist = socket.gethostbyaddr(ip) +- fqdns.update([socket.getfqdn(name)] + [als for als in aliaslist if salt.utils.network.is_fqdn(als)]) ++ return [socket.getfqdn(name)] + [als for als in aliaslist if salt.utils.network.is_fqdn(als)] + except socket.herror as err: + if err.errno == 0: + # No FQDN for this IP address, so we don't need to know this all the time. +@@ -2216,6 +2216,27 @@ def fqdns(): + except (socket.error, socket.gaierror, socket.timeout) as err: + log.error(err_message, err) + ++ start = time.time() ++ ++ addresses = salt.utils.network.ip_addrs(include_loopback=False, interface_data=_get_interfaces()) ++ addresses.extend(salt.utils.network.ip_addrs6(include_loopback=False, interface_data=_get_interfaces())) ++ err_message = 'Exception during resolving address: %s' ++ ++ # Create a ThreadPool to process the underlying calls to 'socket.gethostbyaddr' in parallel. ++ # This avoid blocking the execution when the "fqdn" is not defined for certains IP addresses, which was causing ++ # that "socket.timeout" was reached multiple times secuencially, blocking execution for several seconds. ++ pool = ThreadPool(8) ++ results = pool.map(_lookup_fqdn, addresses) ++ pool.close() ++ pool.join() ++ ++ for item in results: ++ if item: ++ fqdns.update(item) ++ ++ elapsed = time.time() - start ++ log.debug('Elapsed time getting FQDNs: {} seconds'.format(elapsed)) ++ + return {"fqdns": sorted(list(fqdns))} + + +-- +2.17.1 + diff --git a/don-t-call-zypper-with-more-than-one-no-refresh.patch b/don-t-call-zypper-with-more-than-one-no-refresh.patch index aaa65bf..f8a3ebe 100644 --- a/don-t-call-zypper-with-more-than-one-no-refresh.patch +++ b/don-t-call-zypper-with-more-than-one-no-refresh.patch @@ -1,4 +1,4 @@ -From 1c3f8f32d475701e8b7fab64b8cb9dcd44b587d4 Mon Sep 17 00:00:00 2001 +From 5e0fe08c6afd75a7d65d6ccd6cf6b4b197fb1064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= Date: Tue, 29 Jan 2019 09:44:03 +0100 Subject: [PATCH] Don't call zypper with more than one --no-refresh @@ -11,23 +11,23 @@ passed twice. Make sure we won't hit this. 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/modules/zypperpkg.py b/salt/modules/zypperpkg.py -index c442337c58..bab9e22dec 100644 +index 92e7052020..7ac0df26c6 100644 --- a/salt/modules/zypperpkg.py +++ b/salt/modules/zypperpkg.py -@@ -291,7 +291,7 @@ class _Zypper(object): +@@ -282,7 +282,7 @@ class _Zypper(object): self.__called = True if self.__xml: self.__cmd.append('--xmlout') - if not self.__refresh: + if not self.__refresh and '--no-refresh' not in args: self.__cmd.append('--no-refresh') - if self.__root: - self.__cmd.extend(['--root', self.__root]) + + self.__cmd.extend(args) diff --git a/tests/unit/modules/test_zypperpkg.py b/tests/unit/modules/test_zypperpkg.py -index e7474ff777..9d109a431d 100644 +index f586c23fd0..5c5091a570 100644 --- a/tests/unit/modules/test_zypperpkg.py +++ b/tests/unit/modules/test_zypperpkg.py -@@ -141,7 +141,7 @@ class ZypperTestCase(TestCase, LoaderModuleMockMixin): +@@ -138,7 +138,7 @@ class ZypperTestCase(TestCase, LoaderModuleMockMixin): self.assertEqual(zypper.__zypper__.call('foo'), stdout_xml_snippet) self.assertEqual(len(sniffer.calls), 1) diff --git a/fix-async-batch-race-conditions.patch b/fix-async-batch-race-conditions.patch new file mode 100644 index 0000000..6be04b5 --- /dev/null +++ b/fix-async-batch-race-conditions.patch @@ -0,0 +1,253 @@ +From 33c5e10c2912f584243d29c764c2c6cca86edf4a Mon Sep 17 00:00:00 2001 +From: Mihai Dinca +Date: Thu, 11 Apr 2019 15:57:59 +0200 +Subject: [PATCH] Fix async batch race conditions + +Close batching when there is no next batch +--- + salt/cli/batch_async.py | 80 +++++++++++++++--------------- + tests/unit/cli/test_batch_async.py | 35 ++++++------- + 2 files changed, 54 insertions(+), 61 deletions(-) + +diff --git a/salt/cli/batch_async.py b/salt/cli/batch_async.py +index 3160d46d8b..9c20b2fc6e 100644 +--- a/salt/cli/batch_async.py ++++ b/salt/cli/batch_async.py +@@ -37,14 +37,14 @@ class BatchAsync(object): + - tag: salt/batch//start + - data: { + "available_minions": self.minions, +- "down_minions": self.down_minions ++ "down_minions": targeted_minions - presence_ping_minions + } + + When the batch ends, an `done` event is fired: + - tag: salt/batch//done + - data: { + "available_minions": self.minions, +- "down_minions": self.down_minions, ++ "down_minions": targeted_minions - presence_ping_minions + "done_minions": self.done_minions, + "timedout_minions": self.timedout_minions + } +@@ -67,7 +67,7 @@ class BatchAsync(object): + self.eauth = batch_get_eauth(clear_load['kwargs']) + self.metadata = clear_load['kwargs'].get('metadata', {}) + self.minions = set() +- self.down_minions = set() ++ self.targeted_minions = set() + self.timedout_minions = set() + self.done_minions = set() + self.active = set() +@@ -108,8 +108,7 @@ class BatchAsync(object): + minion = data['id'] + if op == 'ping_return': + self.minions.add(minion) +- self.down_minions.remove(minion) +- if not self.down_minions: ++ if self.targeted_minions == self.minions: + self.event.io_loop.spawn_callback(self.start_batch) + elif op == 'find_job_return': + self.find_job_returned.add(minion) +@@ -120,9 +119,6 @@ class BatchAsync(object): + # call later so that we maybe gather more returns + self.event.io_loop.call_later(self.batch_delay, self.schedule_next) + +- if self.initialized and self.done_minions == self.minions.difference(self.timedout_minions): +- self.end_batch() +- + def _get_next(self): + to_run = self.minions.difference( + self.done_minions).difference( +@@ -135,16 +131,13 @@ class BatchAsync(object): + return set(list(to_run)[:next_batch_size]) + + @tornado.gen.coroutine +- def check_find_job(self, minions): +- did_not_return = minions.difference(self.find_job_returned) +- if did_not_return: +- for minion in did_not_return: +- if minion in self.find_job_returned: +- self.find_job_returned.remove(minion) +- if minion in self.active: +- self.active.remove(minion) +- self.timedout_minions.add(minion) +- running = minions.difference(did_not_return).difference(self.done_minions).difference(self.timedout_minions) ++ def check_find_job(self, batch_minions): ++ timedout_minions = batch_minions.difference(self.find_job_returned).difference(self.done_minions) ++ self.timedout_minions = self.timedout_minions.union(timedout_minions) ++ self.active = self.active.difference(self.timedout_minions) ++ running = batch_minions.difference(self.done_minions).difference(self.timedout_minions) ++ if timedout_minions: ++ self.event.io_loop.call_later(self.batch_delay, self.schedule_next) + if running: + self.event.io_loop.add_callback(self.find_job, running) + +@@ -183,7 +176,7 @@ class BatchAsync(object): + jid=self.ping_jid, + metadata=self.metadata, + **self.eauth) +- self.down_minions = set(ping_return['minions']) ++ self.targeted_minions = set(ping_return['minions']) + + @tornado.gen.coroutine + def start_batch(self): +@@ -192,36 +185,43 @@ class BatchAsync(object): + self.initialized = True + data = { + "available_minions": self.minions, +- "down_minions": self.down_minions, ++ "down_minions": self.targeted_minions.difference(self.minions), + "metadata": self.metadata + } + self.event.fire_event(data, "salt/batch/{0}/start".format(self.batch_jid)) + yield self.schedule_next() + + def end_batch(self): +- data = { +- "available_minions": self.minions, +- "down_minions": self.down_minions, +- "done_minions": self.done_minions, +- "timedout_minions": self.timedout_minions, +- "metadata": self.metadata +- } +- self.event.fire_event(data, "salt/batch/{0}/done".format(self.batch_jid)) +- self.event.remove_event_handler(self.__event_handler) ++ left = self.minions.symmetric_difference(self.done_minions.union(self.timedout_minions)) ++ if not left: ++ data = { ++ "available_minions": self.minions, ++ "down_minions": self.targeted_minions.difference(self.minions), ++ "done_minions": self.done_minions, ++ "timedout_minions": self.timedout_minions, ++ "metadata": self.metadata ++ } ++ self.event.fire_event(data, "salt/batch/{0}/done".format(self.batch_jid)) ++ self.event.remove_event_handler(self.__event_handler) + + @tornado.gen.coroutine + def schedule_next(self): + next_batch = self._get_next() + if next_batch: +- yield self.local.run_job_async( +- next_batch, +- self.opts['fun'], +- self.opts['arg'], +- 'list', +- raw=self.opts.get('raw', False), +- ret=self.opts.get('return', ''), +- gather_job_timeout=self.opts['gather_job_timeout'], +- jid=self.batch_jid, +- metadata=self.metadata) +- self.event.io_loop.call_later(self.opts['timeout'], self.find_job, set(next_batch)) + self.active = self.active.union(next_batch) ++ try: ++ yield self.local.run_job_async( ++ next_batch, ++ self.opts['fun'], ++ self.opts['arg'], ++ 'list', ++ raw=self.opts.get('raw', False), ++ ret=self.opts.get('return', ''), ++ gather_job_timeout=self.opts['gather_job_timeout'], ++ jid=self.batch_jid, ++ metadata=self.metadata) ++ self.event.io_loop.call_later(self.opts['timeout'], self.find_job, set(next_batch)) ++ except Exception as ex: ++ self.active = self.active.difference(next_batch) ++ else: ++ self.end_batch() +diff --git a/tests/unit/cli/test_batch_async.py b/tests/unit/cli/test_batch_async.py +index f65b6a06c3..d519157d92 100644 +--- a/tests/unit/cli/test_batch_async.py ++++ b/tests/unit/cli/test_batch_async.py +@@ -75,8 +75,8 @@ class AsyncBatchTestCase(AsyncTestCase, TestCase): + self.batch.local.run_job_async.call_args[0], + ('*', 'test.ping', [], 'glob') + ) +- # assert down_minions == all minions matched by tgt +- self.assertEqual(self.batch.down_minions, set(['foo', 'bar'])) ++ # assert targeted_minions == all minions matched by tgt ++ self.assertEqual(self.batch.targeted_minions, set(['foo', 'bar'])) + + @tornado.testing.gen_test + def test_batch_start_on_gather_job_timeout(self): +@@ -121,7 +121,10 @@ class AsyncBatchTestCase(AsyncTestCase, TestCase): + self.assertEqual(len(self.batch.schedule_next.mock_calls), 1) + + def test_batch_fire_done_event(self): ++ self.batch.targeted_minions = {'foo', 'baz', 'bar'} + self.batch.minions = set(['foo', 'bar']) ++ self.batch.done_minions = {'foo'} ++ self.batch.timedout_minions = {'bar'} + self.batch.event = MagicMock() + self.batch.metadata = {'mykey': 'myvalue'} + self.batch.end_batch() +@@ -130,9 +133,9 @@ class AsyncBatchTestCase(AsyncTestCase, TestCase): + ( + { + 'available_minions': set(['foo', 'bar']), +- 'done_minions': set(), +- 'down_minions': set(), +- 'timedout_minions': set(), ++ 'done_minions': self.batch.done_minions, ++ 'down_minions': {'baz'}, ++ 'timedout_minions': self.batch.timedout_minions, + 'metadata': self.batch.metadata + }, + "salt/batch/1235/done" +@@ -212,7 +215,7 @@ class AsyncBatchTestCase(AsyncTestCase, TestCase): + self.assertEqual(self.batch._get_next(), set()) + + def test_batch__event_handler_ping_return(self): +- self.batch.down_minions = {'foo'} ++ self.batch.targeted_minions = {'foo'} + self.batch.event = MagicMock( + unpack=MagicMock(return_value=('salt/job/1234/ret/foo', {'id': 'foo'}))) + self.batch.start() +@@ -222,7 +225,7 @@ class AsyncBatchTestCase(AsyncTestCase, TestCase): + self.assertEqual(self.batch.done_minions, set()) + + def test_batch__event_handler_call_start_batch_when_all_pings_return(self): +- self.batch.down_minions = {'foo'} ++ self.batch.targeted_minions = {'foo'} + self.batch.event = MagicMock( + unpack=MagicMock(return_value=('salt/job/1234/ret/foo', {'id': 'foo'}))) + self.batch.start() +@@ -232,7 +235,7 @@ class AsyncBatchTestCase(AsyncTestCase, TestCase): + (self.batch.start_batch,)) + + def test_batch__event_handler_not_call_start_batch_when_not_all_pings_return(self): +- self.batch.down_minions = {'foo', 'bar'} ++ self.batch.targeted_minions = {'foo', 'bar'} + self.batch.event = MagicMock( + unpack=MagicMock(return_value=('salt/job/1234/ret/foo', {'id': 'foo'}))) + self.batch.start() +@@ -260,20 +263,10 @@ class AsyncBatchTestCase(AsyncTestCase, TestCase): + self.assertEqual(self.batch.find_job_returned, {'foo'}) + + @tornado.testing.gen_test +- def test_batch__event_handler_end_batch(self): +- self.batch.event = MagicMock( +- unpack=MagicMock(return_value=('salt/job/not-my-jid/ret/foo', {'id': 'foo'}))) +- future = tornado.gen.Future() +- future.set_result({'minions': ['foo', 'bar', 'baz']}) +- self.batch.local.run_job_async.return_value = future +- self.batch.start() +- self.batch.initialized = True +- self.assertEqual(self.batch.down_minions, {'foo', 'bar', 'baz'}) ++ def test_batch_schedule_next_end_batch_when_no_next(self): + self.batch.end_batch = MagicMock() +- self.batch.minions = {'foo', 'bar', 'baz'} +- self.batch.done_minions = {'foo', 'bar'} +- self.batch.timedout_minions = {'baz'} +- self.batch._BatchAsync__event_handler(MagicMock()) ++ self.batch._get_next = MagicMock(return_value={}) ++ self.batch.schedule_next() + self.assertEqual(len(self.batch.end_batch.mock_calls), 1) + + @tornado.testing.gen_test +-- +2.20.1 + + diff --git a/mount-fix-extra-t-parameter.patch b/mount-fix-extra-t-parameter.patch new file mode 100644 index 0000000..a775996 --- /dev/null +++ b/mount-fix-extra-t-parameter.patch @@ -0,0 +1,30 @@ +From 215d8d9c8f872b510a1c3fbb19ab4e91bc96bb64 Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Thu, 28 Feb 2019 15:45:28 +0100 +Subject: [PATCH] mount: fix extra -t parameter + +If 'fstype' parameter is not set in Linux environments, salt will +build a mount command with an empty -t value, making the command +fail. +--- + salt/modules/mount.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/salt/modules/mount.py b/salt/modules/mount.py +index 4ba370e5b3..e807b1729e 100644 +--- a/salt/modules/mount.py ++++ b/salt/modules/mount.py +@@ -1218,7 +1218,8 @@ def mount(name, device, mkmnt=False, fstype='', opts='defaults', user=None, util + if fstype: + args += ' -v {0}'.format(fstype) + else: +- args += ' -t {0}'.format(fstype) ++ if fstype: ++ args += ' -t {0}'.format(fstype) + cmd = 'mount {0} {1} {2} '.format(args, device, name) + out = __salt__['cmd.run_all'](cmd, runas=user, python_shell=False) + if out['retcode']: +-- +2.20.1 + + diff --git a/salt.changes b/salt.changes index 00f5cae..48d54ff 100644 --- a/salt.changes +++ b/salt.changes @@ -1,3 +1,26 @@ +------------------------------------------------------------------- +Fri Apr 26 10:00:01 UTC 2019 - mdinca@suse.de + +- Fix batch/batch-async related issues +- Calculate FQDNs in parallel to avoid blockings (bsc#1129079) +- Incorporate virt.volume_info fixes (PR#131) +- Re-adds patch because of increased offset due to previous patch removal +- Removing patch to add root parameter to zypper module +- Fix for -t parameter in mount module + +- Added: + * mount-fix-extra-t-parameter.patch + * add-batch_presence_ping_timeout-and-batch_presence_p.patch + * fix-async-batch-race-conditions.patch + * calculate-fqdns-in-parallel-to-avoid-blockings-bsc-1.patch + +- Modified: + * don-t-call-zypper-with-more-than-one-no-refresh.patch + * add-virt.volume_infos-and-virt.volume_delete.patch + +- Removed: + * zypper-add-root-configuration-parameter.patch + ------------------------------------------------------------------- Thu Feb 28 16:18:38 UTC 2019 - Jochen Breuer diff --git a/salt.spec b/salt.spec index 743737d..66d4443 100644 --- a/salt.spec +++ b/salt.spec @@ -141,22 +141,28 @@ Patch37: return-the-expected-powerpc-os-arch-bsc-1117995.patch Patch38: remove-arch-from-name-when-pkg.list_pkgs-is-called-w.patch # PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/51119 Patch39: fix-issue-2068-test.patch -# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/50125 -Patch40: zypper-add-root-configuration-parameter.patch # PATCH_FIX_OPENSUSE: Temporary fix allowing "id_" and "force" params while upstrem figures it out -Patch41: temporary-fix-extend-the-whitelist-of-allowed-comman.patch +Patch40: temporary-fix-extend-the-whitelist-of-allowed-comman.patch # PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/51382 -Patch42: don-t-call-zypper-with-more-than-one-no-refresh.patch +Patch41: don-t-call-zypper-with-more-than-one-no-refresh.patch # PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/50109 # PATCH_FIX_OPENSUSE https://github.com/openSUSE/salt/pull/121 -Patch43: add-virt.all_capabilities.patch +Patch42: add-virt.all_capabilities.patch # PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/51691 -Patch44: add-virt.volume_infos-and-virt.volume_delete.patch +Patch43: add-virt.volume_infos-and-virt.volume_delete.patch # PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/51384 -Patch45: include-aliases-in-the-fqdns-grains.patch +Patch44: include-aliases-in-the-fqdns-grains.patch # PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/50546 # PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/51863 -Patch46: async-batch-implementation.patch +Patch45: async-batch-implementation.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/51905 +Patch46: mount-fix-extra-t-parameter.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/52527 +Patch47: calculate-fqdns-in-parallel-to-avoid-blockings-bsc-1.patch +#PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/139 +Patch48: fix-async-batch-race-conditions.patch +#PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/141 +Patch49: add-batch_presence_ping_timeout-and-batch_presence_p.patch # BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -661,6 +667,9 @@ cp %{S:5} ./.travis.yml %patch44 -p1 %patch45 -p1 %patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 %build %if 0%{?build_py2}