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
This commit is contained in:
parent
fc16e6ca2c
commit
9ce4d6f2a0
@ -1 +1 @@
|
|||||||
65afa65b0d69f90c1cd716474cdddcdc98751274
|
8bef2df02d5c189cef341f81679fda05b6c02930
|
46
add-batch_presence_ping_timeout-and-batch_presence_p.patch
Normal file
46
add-batch_presence_ping_timeout-and-batch_presence_p.patch
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
From 902a3527415807448be0aa28a651374a189d102c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marcelo Chiaradia <mchiaradia@suse.com>
|
||||||
|
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
|
||||||
|
|
||||||
|
|
@ -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?= <cbosdonnat@suse.com>
|
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
|
||||||
Date: Fri, 15 Feb 2019 17:28:00 +0100
|
Date: Fri, 15 Feb 2019 17:28:00 +0100
|
||||||
Subject: [PATCH] Add virt.volume_infos() and virt.volume_delete()
|
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.
|
virt.volume_delete() allows removing a given volume.
|
||||||
---
|
---
|
||||||
salt/modules/virt.py | 113 ++++++++++++++++++++
|
salt/modules/virt.py | 126 +++++++++++++++++++++
|
||||||
tests/unit/modules/test_virt.py | 184 ++++++++++++++++++++++++++++++++
|
tests/unit/modules/test_virt.py | 195 ++++++++++++++++++++++++++++++++
|
||||||
2 files changed, 297 insertions(+)
|
2 files changed, 321 insertions(+)
|
||||||
|
|
||||||
diff --git a/salt/modules/virt.py b/salt/modules/virt.py
|
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
|
--- a/salt/modules/virt.py
|
||||||
+++ b/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()
|
return pool.listVolumes()
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
@ -34,6 +34,19 @@ index 0921122a8a..4a301f289c 100644
|
|||||||
+ return pool_obj.storageVolLookupByName(vol)
|
+ 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):
|
+def _get_all_volumes_paths(conn):
|
||||||
+ '''
|
+ '''
|
||||||
+ Extract the path and backing stores path of all volumes.
|
+ 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]
|
+ 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')]
|
+ 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
|
+ 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,
|
+ all the volumes contained in the pool are provided. If no pool is provided,
|
||||||
+ the infos of the volumes of all pools are output.
|
+ the infos of the volumes of all pools are output.
|
||||||
+
|
+
|
||||||
+ :param pool: libvirt storage pool name
|
+ :param pool: libvirt storage pool name (default: ``None``)
|
||||||
+ :param volume: name of the volume to get infos from
|
+ :param volume: name of the volume to get infos from (default: ``None``)
|
||||||
+ :param connection: libvirt connection URI, overriding defaults
|
+ :param connection: libvirt connection URI, overriding defaults
|
||||||
+ :param username: username to connect with, overriding defaults
|
+ :param username: username to connect with, overriding defaults
|
||||||
+ :param password: password 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]
|
+ 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)
|
+ vols = {pool_obj.name(): {vol.name(): _volume_extract_infos(vol)
|
||||||
+ for vol in pool_obj.listAllVolumes()
|
+ 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}
|
+ for pool_obj in pools}
|
||||||
+ return {pool_name: volumes for (pool_name, volumes) in vols.items() if volumes}
|
+ return {pool_name: volumes for (pool_name, volumes) in vols.items() if volumes}
|
||||||
+ except libvirt.libvirtError as err:
|
+ except libvirt.libvirtError as err:
|
||||||
@ -137,10 +150,10 @@ index 0921122a8a..4a301f289c 100644
|
|||||||
+ finally:
|
+ finally:
|
||||||
+ conn.close()
|
+ conn.close()
|
||||||
diff --git a/tests/unit/modules/test_virt.py b/tests/unit/modules/test_virt.py
|
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
|
--- a/tests/unit/modules/test_virt.py
|
||||||
+++ b/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
|
self.mock_conn.storagePoolLookupByName.return_value = mock_pool
|
||||||
# pylint: enable=no-member
|
# pylint: enable=no-member
|
||||||
self.assertEqual(names, virt.pool_list_volumes('default'))
|
self.assertEqual(names, virt.pool_list_volumes('default'))
|
||||||
@ -203,6 +216,13 @@ index bd34962a6a..55005f1d04 100644
|
|||||||
+ 'name': 'pool1',
|
+ 'name': 'pool1',
|
||||||
+ 'volumes': [
|
+ 'volumes': [
|
||||||
+ {
|
+ {
|
||||||
|
+ 'key': '/key/of/vol0bad',
|
||||||
|
+ 'name': 'vol0bad',
|
||||||
|
+ 'path': '/path/to/vol0bad.qcow2',
|
||||||
|
+ 'info': None,
|
||||||
|
+ 'backingStore': None
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
+ 'key': '/key/of/vol1',
|
+ 'key': '/key/of/vol1',
|
||||||
+ 'name': 'vol1',
|
+ 'name': 'vol1',
|
||||||
+ 'path': '/path/to/vol1.qcow2',
|
+ 'path': '/path/to/vol1.qcow2',
|
||||||
@ -230,23 +250,27 @@ index bd34962a6a..55005f1d04 100644
|
|||||||
+ mock_volume.name.return_value = vol_data['name']
|
+ mock_volume.name.return_value = vol_data['name']
|
||||||
+ mock_volume.key.return_value = vol_data['key']
|
+ mock_volume.key.return_value = vol_data['key']
|
||||||
+ mock_volume.path.return_value = '/path/to/{0}.qcow2'.format(vol_data['name'])
|
+ mock_volume.path.return_value = '/path/to/{0}.qcow2'.format(vol_data['name'])
|
||||||
+ mock_volume.info.return_value = vol_data['info']
|
+ if vol_data['info']:
|
||||||
+ backing_store = '''
|
+ mock_volume.info.return_value = vol_data['info']
|
||||||
+ <backingStore>
|
+ backing_store = '''
|
||||||
+ <format>qcow2</format>
|
+ <backingStore>
|
||||||
+ <path>{0}</path>
|
+ <format>qcow2</format>
|
||||||
+ </backingStore>
|
+ <path>{0}</path>
|
||||||
+ '''.format(vol_data['backingStore']) if vol_data['backingStore'] else '<backingStore/>'
|
+ </backingStore>
|
||||||
+ mock_volume.XMLDesc.return_value = '''
|
+ '''.format(vol_data['backingStore']) if vol_data['backingStore'] else '<backingStore/>'
|
||||||
+ <volume type='file'>
|
+ mock_volume.XMLDesc.return_value = '''
|
||||||
+ <name>{0}</name>
|
+ <volume type='file'>
|
||||||
+ <target>
|
+ <name>{0}</name>
|
||||||
+ <format>qcow2</format>
|
+ <target>
|
||||||
+ <path>/path/to/{0}.qcow2</path>
|
+ <format>qcow2</format>
|
||||||
+ </target>
|
+ <path>/path/to/{0}.qcow2</path>
|
||||||
+ {1}
|
+ </target>
|
||||||
+ </volume>
|
+ {1}
|
||||||
+ '''.format(vol_data['name'], backing_store)
|
+ </volume>
|
||||||
|
+ '''.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)
|
+ mock_volumes.append(mock_volume)
|
||||||
+ # pylint: enable=no-member
|
+ # pylint: enable=no-member
|
||||||
+ mock_pool.listAllVolumes.return_value = mock_volumes # pylint: disable=no-member
|
+ mock_pool.listAllVolumes.return_value = mock_volumes # pylint: disable=no-member
|
||||||
|
77
calculate-fqdns-in-parallel-to-avoid-blockings-bsc-1.patch
Normal file
77
calculate-fqdns-in-parallel-to-avoid-blockings-bsc-1.patch
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
From 722b9395a6489da7626e6a388c78bf8e8812190e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
|
||||||
|
<psuarezhernandez@suse.com>
|
||||||
|
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
|
||||||
|
|
@ -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?= <cbosdonnat@suse.com>
|
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
|
||||||
Date: Tue, 29 Jan 2019 09:44:03 +0100
|
Date: Tue, 29 Jan 2019 09:44:03 +0100
|
||||||
Subject: [PATCH] Don't call zypper with more than one --no-refresh
|
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(-)
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/salt/modules/zypperpkg.py b/salt/modules/zypperpkg.py
|
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
|
--- a/salt/modules/zypperpkg.py
|
||||||
+++ b/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
|
self.__called = True
|
||||||
if self.__xml:
|
if self.__xml:
|
||||||
self.__cmd.append('--xmlout')
|
self.__cmd.append('--xmlout')
|
||||||
- if not self.__refresh:
|
- if not self.__refresh:
|
||||||
+ if not self.__refresh and '--no-refresh' not in args:
|
+ if not self.__refresh and '--no-refresh' not in args:
|
||||||
self.__cmd.append('--no-refresh')
|
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
|
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
|
--- a/tests/unit/modules/test_zypperpkg.py
|
||||||
+++ b/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(zypper.__zypper__.call('foo'), stdout_xml_snippet)
|
||||||
self.assertEqual(len(sniffer.calls), 1)
|
self.assertEqual(len(sniffer.calls), 1)
|
||||||
|
|
||||||
|
253
fix-async-batch-race-conditions.patch
Normal file
253
fix-async-batch-race-conditions.patch
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
From 33c5e10c2912f584243d29c764c2c6cca86edf4a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mihai Dinca <mdinca@suse.de>
|
||||||
|
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/<batch-jid>/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/<batch-jid>/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
|
||||||
|
|
||||||
|
|
30
mount-fix-extra-t-parameter.patch
Normal file
30
mount-fix-extra-t-parameter.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From 215d8d9c8f872b510a1c3fbb19ab4e91bc96bb64 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alberto Planas <aplanas@gmail.com>
|
||||||
|
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
|
||||||
|
|
||||||
|
|
23
salt.changes
23
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 <jbreuer@suse.de>
|
Thu Feb 28 16:18:38 UTC 2019 - Jochen Breuer <jbreuer@suse.de>
|
||||||
|
|
||||||
|
25
salt.spec
25
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
|
Patch38: remove-arch-from-name-when-pkg.list_pkgs-is-called-w.patch
|
||||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/51119
|
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/51119
|
||||||
Patch39: fix-issue-2068-test.patch
|
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
|
# 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
|
# 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_UPSTREAM https://github.com/saltstack/salt/pull/50109
|
||||||
# PATCH_FIX_OPENSUSE https://github.com/openSUSE/salt/pull/121
|
# 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
|
# 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
|
# 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/50546
|
||||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/51863
|
# 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
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
@ -661,6 +667,9 @@ cp %{S:5} ./.travis.yml
|
|||||||
%patch44 -p1
|
%patch44 -p1
|
||||||
%patch45 -p1
|
%patch45 -p1
|
||||||
%patch46 -p1
|
%patch46 -p1
|
||||||
|
%patch47 -p1
|
||||||
|
%patch48 -p1
|
||||||
|
%patch49 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%if 0%{?build_py2}
|
%if 0%{?build_py2}
|
||||||
|
Loading…
Reference in New Issue
Block a user