Accepting request 569868 from systemsmanagement:saltstack:testing
- Fix the usage of custom macros on the spec file. - Fix RES7: different dependency names for python-PyYAML and python-MarkupSafe - Build both python2 and python3 binaries together. - Bugfix: errors in external pillar causes crash instead of report of them (bsc#1068446) - Fix 'user.present' when 'gid_from_name' is set but group does not exist. - Added: * bugfix-the-logic-according-to-the-exact-described-pu.patch * return-error-when-gid_from_name-and-group-does-not-e.patch - Fix "No service execution module loaded" issue (bsc#1065792) - Set SHELL environment variable Added: * fix-bsc-1065792.patch * set-shell-environment-variable-64.patch - Removed unnecessary logging on shutdown (bsc#1050003) - Renamed patch that adds grain fqdns Changed: * catching-error-when-pidfile-cannot-be-deleted Removed: * fix-for-pidfile-removal-logging Renamed: * add-fqdns-grains -> feat-add-grain-for-all-fqdns OBS-URL: https://build.opensuse.org/request/show/569868 OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=107
This commit is contained in:
parent
01ad8e1de6
commit
b17d3e3575
26
activate-all-beacons-sources-config-pillar-grains.patch
Normal file
26
activate-all-beacons-sources-config-pillar-grains.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 2a88378d88c2f56b152ef048214728995476244a Mon Sep 17 00:00:00 2001
|
||||
From: Bo Maryniuk <bo@suse.de>
|
||||
Date: Tue, 17 Oct 2017 16:52:33 +0200
|
||||
Subject: [PATCH] Activate all beacons sources: config/pillar/grains
|
||||
|
||||
---
|
||||
salt/minion.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/salt/minion.py b/salt/minion.py
|
||||
index 33cbb8fa0a..10b608cc7a 100644
|
||||
--- a/salt/minion.py
|
||||
+++ b/salt/minion.py
|
||||
@@ -404,7 +404,7 @@ class MinionBase(object):
|
||||
the pillar or grains changed
|
||||
'''
|
||||
if 'config.merge' in functions:
|
||||
- b_conf = functions['config.merge']('beacons', self.opts['beacons'], omit_opts=True)
|
||||
+ b_conf = functions['config.merge']('beacons', self.opts['beacons'])
|
||||
if b_conf:
|
||||
return self.beacons.process(b_conf, self.opts['grains']) # pylint: disable=no-member
|
||||
return []
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
26
avoid-excessive-syslogging-by-watchdog-cronjob-58.patch
Normal file
26
avoid-excessive-syslogging-by-watchdog-cronjob-58.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From a94f7d5739fd38529ebf23a89e6afc164739dd8d Mon Sep 17 00:00:00 2001
|
||||
From: Hubert Mantel <mantel@suse.de>
|
||||
Date: Mon, 27 Nov 2017 13:55:13 +0100
|
||||
Subject: [PATCH] avoid excessive syslogging by watchdog cronjob (#58)
|
||||
|
||||
---
|
||||
pkg/suse/salt-minion | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pkg/suse/salt-minion b/pkg/suse/salt-minion
|
||||
index 2e418094ed..73a91ebd62 100755
|
||||
--- a/pkg/suse/salt-minion
|
||||
+++ b/pkg/suse/salt-minion
|
||||
@@ -55,7 +55,7 @@ WATCHDOG_CRON="/etc/cron.d/salt-minion"
|
||||
|
||||
set_watchdog() {
|
||||
if [ ! -f $WATCHDOG_CRON ]; then
|
||||
- echo -e '* * * * * root /usr/bin/salt-daemon-watcher --with-init\n' > $WATCHDOG_CRON
|
||||
+ echo -e '-* * * * * root /usr/bin/salt-daemon-watcher --with-init\n' > $WATCHDOG_CRON
|
||||
# Kick the watcher for 1 minute immediately, because cron will wake up only afterwards
|
||||
/usr/bin/salt-daemon-watcher --with-init & disown
|
||||
fi
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 49a4e807fb1cb844cec7b7c11b37f6c276f899e4 Mon Sep 17 00:00:00 2001
|
||||
From: Bo Maryniuk <bo@suse.de>
|
||||
Date: Mon, 9 Oct 2017 17:57:48 +0200
|
||||
Subject: [PATCH 5/6] Bugfix: always return a string "list" on unknown job
|
||||
Subject: [PATCH] Bugfix: always return a string "list" on unknown job
|
||||
target type.
|
||||
|
||||
---
|
||||
@ -64,5 +64,6 @@ index 3f4ef296a2..4dbf0d2c6f 100644
|
||||
|
||||
if 'metadata' in job:
|
||||
--
|
||||
2.14.2
|
||||
2.15.1
|
||||
|
||||
|
||||
|
316
bugfix-the-logic-according-to-the-exact-described-pu.patch
Normal file
316
bugfix-the-logic-according-to-the-exact-described-pu.patch
Normal file
@ -0,0 +1,316 @@
|
||||
From 0e1cac43dd8211186d6794602f6da77f612850a7 Mon Sep 17 00:00:00 2001
|
||||
From: Bo Maryniuk <bo@suse.de>
|
||||
Date: Tue, 21 Nov 2017 12:53:11 +0100
|
||||
Subject: [PATCH] Bugfix the logic according to the exact described
|
||||
purpose of the function.
|
||||
|
||||
Rename function from ambiguous name
|
||||
|
||||
Fix and clarify docstring.
|
||||
|
||||
Remove unused variable (no exception, within the try/finally block)
|
||||
|
||||
Bugfix: do not pull '_errors' from unchecked objects
|
||||
|
||||
Bugfix: unit test mistakenly expects pillar errors as a string, while it is a list
|
||||
|
||||
Fix unit test: wrong error types in side effect
|
||||
|
||||
Add unit test for _get_pillar_errors when external and internal pillars are clean
|
||||
|
||||
Add unit test for _get_pillar_errors when external pillar has errors and internal is clean
|
||||
|
||||
Add unit test for _get_pillar_errors when both external and internal pillars contains errors
|
||||
|
||||
Add unit test for _get_pillar_errors when external pillar is clean and internal contains errors
|
||||
|
||||
Use variable, instead of direct value
|
||||
---
|
||||
salt/modules/state.py | 82 +++++++++++++++++++---------------------
|
||||
tests/unit/modules/test_state.py | 75 +++++++++++++++++++++++++++++++-----
|
||||
2 files changed, 103 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/salt/modules/state.py b/salt/modules/state.py
|
||||
index fa5b997ef7..31ffc25dfe 100644
|
||||
--- a/salt/modules/state.py
|
||||
+++ b/salt/modules/state.py
|
||||
@@ -99,17 +99,16 @@ def _set_retcode(ret, highstate=None):
|
||||
__context__['retcode'] = 2
|
||||
|
||||
|
||||
-def _check_pillar(kwargs, pillar=None):
|
||||
+def _get_pillar_errors(kwargs, pillar=None):
|
||||
'''
|
||||
- Check the pillar for errors, refuse to run the state if there are errors
|
||||
- in the pillar and return the pillar errors
|
||||
+ Checks all pillars (external and internal) for errors.
|
||||
+ Return an error message, if anywhere or None.
|
||||
+
|
||||
+ :param kwargs: dictionary of options
|
||||
+ :param pillar: external pillar
|
||||
+ :return: None or an error message
|
||||
'''
|
||||
- if kwargs.get('force'):
|
||||
- return True
|
||||
- pillar_dict = pillar if pillar is not None else __pillar__
|
||||
- if '_errors' in pillar_dict:
|
||||
- return False
|
||||
- return True
|
||||
+ return None if kwargs.get('force') else (pillar or {}).get('_errors', __pillar__.get('_errors')) or None
|
||||
|
||||
|
||||
def _wait(jid):
|
||||
@@ -411,10 +410,10 @@ def template(tem, queue=False, **kwargs):
|
||||
context=__context__,
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- raise CommandExecutionError('Pillar failed to render',
|
||||
- info=st_.opts['pillar']['_errors'])
|
||||
+ raise CommandExecutionError('Pillar failed to render', info=errors)
|
||||
|
||||
if not tem.endswith('.sls'):
|
||||
tem = '{sls}.sls'.format(sls=tem)
|
||||
@@ -872,11 +871,10 @@ def highstate(test=None, queue=False, **kwargs):
|
||||
mocked=kwargs.get('mock', False),
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- err = ['Pillar failed to render with the following messages:']
|
||||
- err += __pillar__['_errors']
|
||||
- return err
|
||||
+ return ['Pillar failed to render with the following messages:'] + errors
|
||||
|
||||
st_.push_active()
|
||||
ret = {}
|
||||
@@ -1071,11 +1069,10 @@ def sls(mods, test=None, exclude=None, queue=False, **kwargs):
|
||||
mocked=kwargs.get('mock', False),
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- err = ['Pillar failed to render with the following messages:']
|
||||
- err += __pillar__['_errors']
|
||||
- return err
|
||||
+ return ['Pillar failed to render with the following messages:'] + errors
|
||||
|
||||
orchestration_jid = kwargs.get('orchestration_jid')
|
||||
umask = os.umask(0o77)
|
||||
@@ -1090,7 +1087,6 @@ def sls(mods, test=None, exclude=None, queue=False, **kwargs):
|
||||
mods = mods.split(',')
|
||||
|
||||
st_.push_active()
|
||||
- ret = {}
|
||||
try:
|
||||
high_, errors = st_.render_highstate({opts['environment']: mods})
|
||||
|
||||
@@ -1197,11 +1193,10 @@ def top(topfn, test=None, queue=False, **kwargs):
|
||||
pillar_enc=pillar_enc,
|
||||
context=__context__,
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- err = ['Pillar failed to render with the following messages:']
|
||||
- err += __pillar__['_errors']
|
||||
- return err
|
||||
+ return ['Pillar failed to render with the following messages:'] + errors
|
||||
|
||||
st_.push_active()
|
||||
st_.opts['state_top'] = salt.utils.url.create(topfn)
|
||||
@@ -1259,10 +1254,10 @@ def show_highstate(queue=False, **kwargs):
|
||||
pillar_enc=pillar_enc,
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- raise CommandExecutionError('Pillar failed to render',
|
||||
- info=st_.opts['pillar']['_errors'])
|
||||
+ raise CommandExecutionError('Pillar failed to render', info=errors)
|
||||
|
||||
st_.push_active()
|
||||
try:
|
||||
@@ -1293,10 +1288,10 @@ def show_lowstate(queue=False, **kwargs):
|
||||
st_ = salt.state.HighState(opts,
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- raise CommandExecutionError('Pillar failed to render',
|
||||
- info=st_.opts['pillar']['_errors'])
|
||||
+ raise CommandExecutionError('Pillar failed to render', info=errors)
|
||||
|
||||
st_.push_active()
|
||||
try:
|
||||
@@ -1394,11 +1389,10 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
||||
st_ = salt.state.HighState(opts,
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- err = ['Pillar failed to render with the following messages:']
|
||||
- err += __pillar__['_errors']
|
||||
- return err
|
||||
+ return ['Pillar failed to render with the following messages:'] + errors
|
||||
|
||||
if isinstance(mods, six.string_types):
|
||||
split_mods = mods.split(',')
|
||||
@@ -1474,10 +1468,10 @@ def show_low_sls(mods, test=None, queue=False, **kwargs):
|
||||
|
||||
st_ = salt.state.HighState(opts, initial_pillar=_get_initial_pillar(opts))
|
||||
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- raise CommandExecutionError('Pillar failed to render',
|
||||
- info=st_.opts['pillar']['_errors'])
|
||||
+ raise CommandExecutionError('Pillar failed to render', info=errors)
|
||||
|
||||
if isinstance(mods, six.string_types):
|
||||
mods = mods.split(',')
|
||||
@@ -1561,10 +1555,10 @@ def show_sls(mods, test=None, queue=False, **kwargs):
|
||||
pillar_enc=pillar_enc,
|
||||
initial_pillar=_get_initial_pillar(opts))
|
||||
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- raise CommandExecutionError('Pillar failed to render',
|
||||
- info=st_.opts['pillar']['_errors'])
|
||||
+ raise CommandExecutionError('Pillar failed to render', info=errors)
|
||||
|
||||
if isinstance(mods, six.string_types):
|
||||
mods = mods.split(',')
|
||||
@@ -1610,10 +1604,10 @@ def show_top(queue=False, **kwargs):
|
||||
|
||||
st_ = salt.state.HighState(opts, initial_pillar=_get_initial_pillar(opts))
|
||||
|
||||
- if not _check_pillar(kwargs, st_.opts['pillar']):
|
||||
+ errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
|
||||
+ if errors:
|
||||
__context__['retcode'] = 5
|
||||
- raise CommandExecutionError('Pillar failed to render',
|
||||
- info=st_.opts['pillar']['_errors'])
|
||||
+ raise CommandExecutionError('Pillar failed to render', info=errors)
|
||||
|
||||
errors = []
|
||||
top_ = st_.get_top()
|
||||
diff --git a/tests/unit/modules/test_state.py b/tests/unit/modules/test_state.py
|
||||
index 7f4f361c26..e5d10493da 100644
|
||||
--- a/tests/unit/modules/test_state.py
|
||||
+++ b/tests/unit/modules/test_state.py
|
||||
@@ -695,9 +695,9 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
||||
with patch.object(state, '_check_queue', mock):
|
||||
self.assertEqual(state.top("reverse_top.sls"), "A")
|
||||
|
||||
- mock = MagicMock(side_effect=[False, True, True])
|
||||
- with patch.object(state, '_check_pillar', mock):
|
||||
- with patch.dict(state.__pillar__, {"_errors": "E"}):
|
||||
+ mock = MagicMock(side_effect=[['E'], None, None])
|
||||
+ with patch.object(state, '_get_pillar_errors', mock):
|
||||
+ with patch.dict(state.__pillar__, {"_errors": ['E']}):
|
||||
self.assertListEqual(state.top("reverse_top.sls"), ret)
|
||||
|
||||
with patch.dict(state.__opts__, {"test": "A"}):
|
||||
@@ -854,14 +854,10 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
||||
True),
|
||||
["A"])
|
||||
|
||||
- mock = MagicMock(side_effect=[False,
|
||||
- True,
|
||||
- True,
|
||||
- True,
|
||||
- True])
|
||||
- with patch.object(state, '_check_pillar', mock):
|
||||
+ mock = MagicMock(side_effect=[['E', '1'], None, None, None, None])
|
||||
+ with patch.object(state, '_get_pillar_errors', mock):
|
||||
with patch.dict(state.__context__, {"retcode": 5}):
|
||||
- with patch.dict(state.__pillar__, {"_errors": "E1"}):
|
||||
+ with patch.dict(state.__pillar__, {"_errors": ['E', '1']}):
|
||||
self.assertListEqual(state.sls("core,edit.vim dev",
|
||||
None,
|
||||
None,
|
||||
@@ -979,3 +975,62 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
||||
with patch('salt.utils.fopen', mock_open()):
|
||||
self.assertTrue(state.pkg("/tmp/state_pkg.tgz",
|
||||
0, "md5"))
|
||||
+
|
||||
+ def test_get_pillar_errors_CC(self):
|
||||
+ '''
|
||||
+ Test _get_pillar_errors function.
|
||||
+ CC: External clean, Internal clean
|
||||
+ :return:
|
||||
+ '''
|
||||
+ for int_pillar, ext_pillar in [({'foo': 'bar'}, {'fred': 'baz'}),
|
||||
+ ({'foo': 'bar'}, None),
|
||||
+ ({}, {'fred': 'baz'})]:
|
||||
+ with patch('salt.modules.state.__pillar__', int_pillar):
|
||||
+ for opts, res in [({'force': True}, None),
|
||||
+ ({'force': False}, None),
|
||||
+ ({}, None)]:
|
||||
+ assert res == state._get_pillar_errors(kwargs=opts, pillar=ext_pillar)
|
||||
+
|
||||
+ def test_get_pillar_errors_EC(self):
|
||||
+ '''
|
||||
+ Test _get_pillar_errors function.
|
||||
+ EC: External erroneous, Internal clean
|
||||
+ :return:
|
||||
+ '''
|
||||
+ errors = ['failure', 'everywhere']
|
||||
+ for int_pillar, ext_pillar in [({'foo': 'bar'}, {'fred': 'baz', '_errors': errors}),
|
||||
+ ({}, {'fred': 'baz', '_errors': errors})]:
|
||||
+ with patch('salt.modules.state.__pillar__', int_pillar):
|
||||
+ for opts, res in [({'force': True}, None),
|
||||
+ ({'force': False}, errors),
|
||||
+ ({}, errors)]:
|
||||
+ assert res == state._get_pillar_errors(kwargs=opts, pillar=ext_pillar)
|
||||
+
|
||||
+ def test_get_pillar_errors_EE(self):
|
||||
+ '''
|
||||
+ Test _get_pillar_errors function.
|
||||
+ CC: External erroneous, Internal erroneous
|
||||
+ :return:
|
||||
+ '''
|
||||
+ errors = ['failure', 'everywhere']
|
||||
+ for int_pillar, ext_pillar in [({'foo': 'bar', '_errors': errors}, {'fred': 'baz', '_errors': errors})]:
|
||||
+ with patch('salt.modules.state.__pillar__', int_pillar):
|
||||
+ for opts, res in [({'force': True}, None),
|
||||
+ ({'force': False}, errors),
|
||||
+ ({}, errors)]:
|
||||
+ assert res == state._get_pillar_errors(kwargs=opts, pillar=ext_pillar)
|
||||
+
|
||||
+ def test_get_pillar_errors_CE(self):
|
||||
+ '''
|
||||
+ Test _get_pillar_errors function.
|
||||
+ CC: External clean, Internal erroneous
|
||||
+ :return:
|
||||
+ '''
|
||||
+ errors = ['failure', 'everywhere']
|
||||
+ for int_pillar, ext_pillar in [({'foo': 'bar', '_errors': errors}, {'fred': 'baz'}),
|
||||
+ ({'foo': 'bar', '_errors': errors}, None)]:
|
||||
+ with patch('salt.modules.state.__pillar__', int_pillar):
|
||||
+ for opts, res in [({'force': True}, None),
|
||||
+ ({'force': False}, errors),
|
||||
+ ({}, errors)]:
|
||||
+ assert res == state._get_pillar_errors(kwargs=opts, pillar=ext_pillar)
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
115
catching-error-when-pidfile-cannot-be-deleted.patch
Normal file
115
catching-error-when-pidfile-cannot-be-deleted.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From 16dc0e5ef2c86a315a0d09fb186dd1616df1444e Mon Sep 17 00:00:00 2001
|
||||
From: Jochen Breuer <jbreuer@suse.de>
|
||||
Date: Wed, 6 Sep 2017 10:16:51 +0200
|
||||
Subject: [PATCH] Catching error when PIDfile cannot be deleted
|
||||
|
||||
Usually the PIDfile is locate in /run. If Salt is not started with root
|
||||
permissions, it is not able to delete the PIDfile in /run. It should
|
||||
be safe to just ignore this error, since Salt overwrites the PIDfile on
|
||||
the next start.
|
||||
---
|
||||
salt/utils/parsers.py | 8 +++++-
|
||||
tests/unit/utils/test_parsers.py | 54 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 61 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/salt/utils/parsers.py b/salt/utils/parsers.py
|
||||
index 925ec9f4e4..d8c5068874 100644
|
||||
--- a/salt/utils/parsers.py
|
||||
+++ b/salt/utils/parsers.py
|
||||
@@ -966,7 +966,13 @@ class DaemonMixIn(six.with_metaclass(MixInMeta, object)):
|
||||
# We've loaded and merged options into the configuration, it's safe
|
||||
# to query about the pidfile
|
||||
if self.check_pidfile():
|
||||
- os.unlink(self.config['pidfile'])
|
||||
+ try:
|
||||
+ os.unlink(self.config['pidfile'])
|
||||
+ except OSError as err:
|
||||
+ # This happens when running salt-master as a non-root user
|
||||
+ # and can be ignored, since salt-master is able to
|
||||
+ # overwrite the PIDfile on the next start.
|
||||
+ pass
|
||||
|
||||
def set_pidfile(self):
|
||||
from salt.utils.process import set_pidfile
|
||||
diff --git a/tests/unit/utils/test_parsers.py b/tests/unit/utils/test_parsers.py
|
||||
index 43488e894c..8168b3e6e3 100644
|
||||
--- a/tests/unit/utils/test_parsers.py
|
||||
+++ b/tests/unit/utils/test_parsers.py
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
+import logging
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from tests.support.unit import skipIf, TestCase
|
||||
@@ -21,6 +22,7 @@ import salt.utils.parsers
|
||||
import salt.log.setup as log
|
||||
import salt.config
|
||||
import salt.syspaths
|
||||
+from salt.utils.parsers import DaemonMixIn
|
||||
|
||||
|
||||
class ErrorMock(object): # pylint: disable=too-few-public-methods
|
||||
@@ -958,5 +960,57 @@ class SaltAPIParserTestCase(LogSettingsParserTests):
|
||||
self.addCleanup(delattr, self, 'parser')
|
||||
|
||||
|
||||
+@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
+class DaemonMixInTestCase(TestCase):
|
||||
+ '''
|
||||
+ Tests the PIDfile deletion in the DaemonMixIn.
|
||||
+ '''
|
||||
+
|
||||
+ def setUp(self):
|
||||
+ '''
|
||||
+ Setting up
|
||||
+ '''
|
||||
+ # Set PID
|
||||
+ self.pid = '/some/fake.pid'
|
||||
+
|
||||
+ # Setup mixin
|
||||
+ self.mixin = salt.utils.parsers.DaemonMixIn()
|
||||
+ self.mixin.config = {}
|
||||
+ self.mixin.config['pidfile'] = self.pid
|
||||
+
|
||||
+ # logger
|
||||
+ self.logger = logging.getLogger('salt.utils.parsers')
|
||||
+
|
||||
+ def test_pid_file_deletion(self):
|
||||
+ '''
|
||||
+ PIDfile deletion without exception.
|
||||
+ '''
|
||||
+ with patch('os.unlink', MagicMock()) as os_unlink:
|
||||
+ with patch('os.path.isfile', MagicMock(return_value=True)):
|
||||
+ with patch.object(self.logger, 'info') as mock_logger:
|
||||
+ self.mixin._mixin_before_exit()
|
||||
+ assert mock_logger.call_count == 0
|
||||
+ assert os_unlink.call_count == 1
|
||||
+
|
||||
+
|
||||
# Hide the class from unittest framework when it searches for TestCase classes in the module
|
||||
del LogSettingsParserTests
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ from integration import run_tests # pylint: disable=import-error,wrong-import-position
|
||||
+ run_tests(MasterOptionParserTestCase,
|
||||
+ MinionOptionParserTestCase,
|
||||
+ ProxyMinionOptionParserTestCase,
|
||||
+ SyndicOptionParserTestCase,
|
||||
+ SaltCMDOptionParserTestCase,
|
||||
+ SaltCPOptionParserTestCase,
|
||||
+ SaltKeyOptionParserTestCase,
|
||||
+ SaltCallOptionParserTestCase,
|
||||
+ SaltRunOptionParserTestCase,
|
||||
+ SaltSSHOptionParserTestCase,
|
||||
+ SaltCloudParserTestCase,
|
||||
+ SPMParserTestCase,
|
||||
+ SaltAPIParserTestCase,
|
||||
+ DaemonMixInTestCase,
|
||||
+ needs_daemon=False)
|
||||
--
|
||||
2.13.6
|
||||
|
||||
|
117
cherrypy-read-reads-bytes-from-the-wire-and-write-th.patch
Normal file
117
cherrypy-read-reads-bytes-from-the-wire-and-write-th.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From b31d8f3898149209097e01bbeefbfb70b5a0c395 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Calmer <mc@suse.de>
|
||||
Date: Fri, 15 Dec 2017 09:53:10 +0100
|
||||
Subject: [PATCH] cherrypy read() reads bytes from the wire and write
|
||||
them into contents var
|
||||
|
||||
adapt tests to reflect reality
|
||||
|
||||
When CherryPy run with python3 it reads "bytes" from the wire.
|
||||
In case of python2 BytesIO == StringIO, so nothing should change.
|
||||
|
||||
This change will do the same to make unit tests reflect reality.
|
||||
---
|
||||
salt/netapi/rest_cherrypy/app.py | 25 +++++++------------------
|
||||
tests/support/cptestcase.py | 6 ++++--
|
||||
2 files changed, 11 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/salt/netapi/rest_cherrypy/app.py b/salt/netapi/rest_cherrypy/app.py
|
||||
index 4099416a28..67e0bad07a 100644
|
||||
--- a/salt/netapi/rest_cherrypy/app.py
|
||||
+++ b/salt/netapi/rest_cherrypy/app.py
|
||||
@@ -505,6 +505,7 @@ import salt
|
||||
import salt.auth
|
||||
import salt.utils
|
||||
import salt.utils.event
|
||||
+from salt.ext.six import BytesIO
|
||||
|
||||
# Import salt-api libs
|
||||
import salt.netapi
|
||||
@@ -830,18 +831,6 @@ def urlencoded_processor(entity):
|
||||
|
||||
:param entity: raw POST data
|
||||
'''
|
||||
- if six.PY3:
|
||||
- # https://github.com/cherrypy/cherrypy/pull/1572
|
||||
- contents = six.StringIO()
|
||||
- entity.fp.read(fp_out=contents)
|
||||
- contents.seek(0)
|
||||
- body_str = contents.read()
|
||||
- body_bytes = salt.utils.to_bytes(body_str)
|
||||
- body_bytes = six.BytesIO(body_bytes)
|
||||
- body_bytes.seek(0)
|
||||
- # Patch fp
|
||||
- entity.fp = body_bytes
|
||||
- del contents
|
||||
# First call out to CherryPy's default processor
|
||||
cherrypy._cpreqbody.process_urlencoded(entity)
|
||||
cherrypy._cpreqbody.process_urlencoded(entity)
|
||||
@@ -860,10 +849,10 @@ def json_processor(entity):
|
||||
body = entity.fp.read()
|
||||
else:
|
||||
# https://github.com/cherrypy/cherrypy/pull/1572
|
||||
- contents = six.StringIO()
|
||||
+ contents = BytesIO()
|
||||
body = entity.fp.read(fp_out=contents)
|
||||
contents.seek(0)
|
||||
- body = contents.read()
|
||||
+ body = salt.utils.to_unicode(contents.read())
|
||||
del contents
|
||||
try:
|
||||
cherrypy.serving.request.unserialized_data = json.loads(body)
|
||||
@@ -884,10 +873,10 @@ def yaml_processor(entity):
|
||||
body = entity.fp.read()
|
||||
else:
|
||||
# https://github.com/cherrypy/cherrypy/pull/1572
|
||||
- contents = six.StringIO()
|
||||
+ contents = BytesIO()
|
||||
body = entity.fp.read(fp_out=contents)
|
||||
contents.seek(0)
|
||||
- body = contents.read()
|
||||
+ body = salt.utils.to_unicode(contents.read())
|
||||
try:
|
||||
cherrypy.serving.request.unserialized_data = yaml.safe_load(body)
|
||||
except ValueError:
|
||||
@@ -910,10 +899,10 @@ def text_processor(entity):
|
||||
body = entity.fp.read()
|
||||
else:
|
||||
# https://github.com/cherrypy/cherrypy/pull/1572
|
||||
- contents = six.StringIO()
|
||||
+ contents = BytesIO()
|
||||
body = entity.fp.read(fp_out=contents)
|
||||
contents.seek(0)
|
||||
- body = contents.read()
|
||||
+ body = salt.utils.to_unicode(contents.read())
|
||||
try:
|
||||
cherrypy.serving.request.unserialized_data = json.loads(body)
|
||||
except ValueError:
|
||||
diff --git a/tests/support/cptestcase.py b/tests/support/cptestcase.py
|
||||
index ea2845f46d..75785b8eb1 100644
|
||||
--- a/tests/support/cptestcase.py
|
||||
+++ b/tests/support/cptestcase.py
|
||||
@@ -38,9 +38,11 @@ from tests.support.case import TestCase
|
||||
# pylint: disable=import-error
|
||||
import cherrypy # pylint: disable=3rd-party-module-not-gated
|
||||
import salt.ext.six as six
|
||||
-from salt.ext.six.moves import StringIO
|
||||
+from salt.ext.six import BytesIO
|
||||
# pylint: enable=import-error
|
||||
|
||||
+import salt.utils
|
||||
+
|
||||
# Not strictly speaking mandatory but just makes sense
|
||||
cherrypy.config.update({'environment': "test_suite"})
|
||||
|
||||
@@ -92,7 +94,7 @@ class BaseCherryPyTestCase(TestCase):
|
||||
fd = None
|
||||
if body is not None:
|
||||
h['content-length'] = '{0}'.format(len(body))
|
||||
- fd = StringIO(body)
|
||||
+ fd = BytesIO(salt.utils.to_bytes(body))
|
||||
|
||||
if headers is not None:
|
||||
h.update(headers)
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
@ -2,7 +2,7 @@ From 1949261a504fd01e057b41126d78f142f4977204 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
|
||||
<psuarezhernandez@suse.com>
|
||||
Date: Fri, 6 Oct 2017 17:12:15 +0100
|
||||
Subject: [PATCH 6/6] Enable '--with-salt-version' parameter for setup.py
|
||||
Subject: [PATCH] Enable '--with-salt-version' parameter for setup.py
|
||||
script
|
||||
|
||||
---
|
||||
@ -71,5 +71,6 @@ index effdc2f230..519f753401 100755
|
||||
self.salt_version = __version__ # pylint: disable=undefined-variable
|
||||
self.description = 'Portable, distributed, remote execution and configuration management system'
|
||||
--
|
||||
2.14.2
|
||||
2.15.1
|
||||
|
||||
|
||||
|
0
fake-fix.patch
Normal file
0
fake-fix.patch
Normal file
119
feat-add-grain-for-all-fqdns.patch
Normal file
119
feat-add-grain-for-all-fqdns.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From ba9f26cf00b0a767b7b25f156553a9e783aa895d Mon Sep 17 00:00:00 2001
|
||||
From: Michele Bologna <michele.bologna@suse.com>
|
||||
Date: Thu, 14 Dec 2017 18:20:02 +0100
|
||||
Subject: [PATCH] Feat: add grain for all FQDNs
|
||||
|
||||
This PR adds a grain named fqdns to the grains.
|
||||
fqdns represents all the FQDNs known for the system on all available interfaces (excluding lo).
|
||||
|
||||
Note: hostname != FQDN
|
||||
|
||||
hostname is the UNIX name of the machine. A machine can have one and only one hostname.
|
||||
FQDN is host.domain that resolves to an IP address that the machines is answering to.
|
||||
A machine can have 1+ FQDNs.
|
||||
|
||||
Upstream PR:
|
||||
https://github.com/saltstack/salt/pull/45060
|
||||
---
|
||||
salt/grains/core.py | 27 +++++++++++++++++++++++++++
|
||||
tests/integration/modules/test_grains.py | 1 +
|
||||
tests/unit/grains/test_core.py | 28 ++++++++++++++++++++++++++++
|
||||
3 files changed, 56 insertions(+)
|
||||
|
||||
diff --git a/salt/grains/core.py b/salt/grains/core.py
|
||||
index a7e1a22d2a..04b73f9120 100644
|
||||
--- a/salt/grains/core.py
|
||||
+++ b/salt/grains/core.py
|
||||
@@ -1756,6 +1756,33 @@ def append_domain():
|
||||
return grain
|
||||
|
||||
|
||||
+def fqdns():
|
||||
+ '''
|
||||
+ Return all known FQDNs for the system by enumerating all interfaces and
|
||||
+ then trying to reverse resolve them (excluding 'lo' interface).
|
||||
+ '''
|
||||
+ # Provides:
|
||||
+ # fqdns
|
||||
+
|
||||
+ grains = {}
|
||||
+ fqdns = set()
|
||||
+
|
||||
+ addresses = salt.utils.network.ip_addrs(include_loopback=False,
|
||||
+ interface_data=_INTERFACES)
|
||||
+ addresses.extend(salt.utils.network.ip_addrs6(include_loopback=False,
|
||||
+ interface_data=_INTERFACES))
|
||||
+
|
||||
+ for ip in addresses:
|
||||
+ try:
|
||||
+ fqdns.add(socket.gethostbyaddr(ip)[0])
|
||||
+ except (socket.error, socket.herror,
|
||||
+ socket.gaierror, socket.timeout) as e:
|
||||
+ log.error("Exception during resolving address: " + str(e))
|
||||
+
|
||||
+ grains['fqdns'] = list(fqdns)
|
||||
+ return grains
|
||||
+
|
||||
+
|
||||
def ip_fqdn():
|
||||
'''
|
||||
Return ip address and FQDN grains
|
||||
diff --git a/tests/integration/modules/test_grains.py b/tests/integration/modules/test_grains.py
|
||||
index 7d46315e42..1db90ab532 100644
|
||||
--- a/tests/integration/modules/test_grains.py
|
||||
+++ b/tests/integration/modules/test_grains.py
|
||||
@@ -51,6 +51,7 @@ class TestModulesGrains(ModuleCase):
|
||||
'cpuarch',
|
||||
'domain',
|
||||
'fqdn',
|
||||
+ 'fqdns',
|
||||
'gid',
|
||||
'groupname',
|
||||
'host',
|
||||
diff --git a/tests/unit/grains/test_core.py b/tests/unit/grains/test_core.py
|
||||
index 6ee4257863..4f1412de76 100644
|
||||
--- a/tests/unit/grains/test_core.py
|
||||
+++ b/tests/unit/grains/test_core.py
|
||||
@@ -6,6 +6,7 @@
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
+import socket
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
@@ -462,3 +463,30 @@ PATCHLEVEL = 3
|
||||
self.assertEqual(os_grains.get('osrelease'), os_release_map['osrelease'])
|
||||
self.assertListEqual(list(os_grains.get('osrelease_info')), os_release_map['osrelease_info'])
|
||||
self.assertEqual(os_grains.get('osmajorrelease'), os_release_map['osmajorrelease'])
|
||||
+
|
||||
+ @skipIf(not salt.utils.is_linux(), 'System is not Linux')
|
||||
+ def test_fqdns_return(self):
|
||||
+ '''
|
||||
+ test the return for a dns grain. test for issue:
|
||||
+ https://github.com/saltstack/salt/issues/41230
|
||||
+ '''
|
||||
+ reverse_resolv_mock = [('foo.bar.baz', [], ['1.2.3.4']),
|
||||
+ ('rinzler.evil-corp.com', [], ['5.6.7.8']),
|
||||
+ ('foo.bar.baz', [], ['fe80::a8b2:93ff:fe00:0']),
|
||||
+ ('bluesniff.foo.bar', [], ['fe80::a8b2:93ff:dead:beef'])]
|
||||
+ ret = {'fqdns': ['rinzler.evil-corp.com', 'foo.bar.baz', 'bluesniff.foo.bar']}
|
||||
+ self._run_fqdns_test(reverse_resolv_mock, ret)
|
||||
+
|
||||
+ def _run_fqdns_test(self, reverse_resolv_mock, ret):
|
||||
+ with patch.object(salt.utils, 'is_windows', MagicMock(return_value=False)):
|
||||
+ with patch('salt.utils.network.ip_addrs',
|
||||
+ MagicMock(return_value=['1.2.3.4', '5.6.7.8'])),\
|
||||
+ patch('salt.utils.network.ip_addrs6',
|
||||
+ MagicMock(return_value=['fe80::a8b2:93ff:fe00:0', 'fe80::a8b2:93ff:dead:beef'])):
|
||||
+ with patch.object(socket, 'gethostbyaddr', side_effect=reverse_resolv_mock):
|
||||
+ fqdns = core.fqdns()
|
||||
+ self.assertEqual(fqdns, ret)
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ from integration import run_tests
|
||||
+ run_tests(CoreGrainsTestCase, needs_daemon=False)
|
||||
--
|
||||
2.13.6
|
||||
|
||||
|
25
fix-bsc-1065792.patch
Normal file
25
fix-bsc-1065792.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From e6b1c05fb9e38e54ad30a540a32cd8491fee286b Mon Sep 17 00:00:00 2001
|
||||
From: Bo Maryniuk <bo@suse.de>
|
||||
Date: Thu, 14 Dec 2017 16:21:40 +0100
|
||||
Subject: [PATCH] Fix bsc#1065792
|
||||
|
||||
---
|
||||
salt/states/service.py | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/salt/states/service.py b/salt/states/service.py
|
||||
index ff5300df6a..eaa9474f78 100644
|
||||
--- a/salt/states/service.py
|
||||
+++ b/salt/states/service.py
|
||||
@@ -80,6 +80,7 @@ def __virtual__():
|
||||
Only make these states available if a service provider has been detected or
|
||||
assigned for this minion
|
||||
'''
|
||||
+ __salt__._load_all()
|
||||
if 'service.start' in __salt__:
|
||||
return __virtualname__
|
||||
else:
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
253
fix-for-delete_deployment-in-kubernetes-module.patch
Normal file
253
fix-for-delete_deployment-in-kubernetes-module.patch
Normal file
@ -0,0 +1,253 @@
|
||||
From 01c4d8875a8be8b0707b0088ccf186c4cd137448 Mon Sep 17 00:00:00 2001
|
||||
From: Jochen Breuer <jbreuer@suse.de>
|
||||
Date: Wed, 23 Aug 2017 21:31:28 +0200
|
||||
Subject: [PATCH] Fix for delete_deployment in Kubernetes module
|
||||
|
||||
The Kubernetes module function delete_deployment() uses
|
||||
api_instance.delete_namespaced_deployment() from the Kubernetes lib. This
|
||||
method from the Kubernetes lib returns immediately without giving a success
|
||||
or failure indication, which lets Salt mark the job as failed even though we
|
||||
don't know if it failed or not.
|
||||
|
||||
To actually get a result I've implemented a polling via show_deployment() to
|
||||
check if the deployment got removed.
|
||||
|
||||
If a time limit is hit, we are returning with an error, otherwise it is a
|
||||
success.
|
||||
|
||||
Since Windows has no signal.alarm implementation, we are here falling back to
|
||||
loop counting.
|
||||
---
|
||||
salt/exceptions.py | 6 ++
|
||||
salt/modules/kubernetes.py | 44 +++++++++++-
|
||||
tests/unit/modules/test_kubernetes.py | 126 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 175 insertions(+), 1 deletion(-)
|
||||
create mode 100644 tests/unit/modules/test_kubernetes.py
|
||||
|
||||
diff --git a/salt/exceptions.py b/salt/exceptions.py
|
||||
index 256537dd77..00111df104 100644
|
||||
--- a/salt/exceptions.py
|
||||
+++ b/salt/exceptions.py
|
||||
@@ -265,6 +265,12 @@ class SaltCacheError(SaltException):
|
||||
'''
|
||||
|
||||
|
||||
+class TimeoutError(SaltException):
|
||||
+ '''
|
||||
+ Thrown when an opration cannot be completet within a given time limit.
|
||||
+ '''
|
||||
+
|
||||
+
|
||||
class SaltReqTimeoutError(SaltException):
|
||||
'''
|
||||
Thrown when a salt master request call fails to return within the timeout
|
||||
diff --git a/salt/modules/kubernetes.py b/salt/modules/kubernetes.py
|
||||
index 2e17b11444..890659c1c8 100644
|
||||
--- a/salt/modules/kubernetes.py
|
||||
+++ b/salt/modules/kubernetes.py
|
||||
@@ -40,11 +40,15 @@ import base64
|
||||
import logging
|
||||
import yaml
|
||||
import tempfile
|
||||
+import signal
|
||||
+from time import sleep
|
||||
+from contextlib import contextmanager
|
||||
|
||||
from salt.exceptions import CommandExecutionError
|
||||
from salt.ext.six import iteritems
|
||||
import salt.utils
|
||||
import salt.utils.templates
|
||||
+from salt.ext.six.moves import range # pylint: disable=import-error
|
||||
|
||||
try:
|
||||
import kubernetes # pylint: disable=import-self
|
||||
@@ -78,6 +82,21 @@ def __virtual__():
|
||||
return False, 'python kubernetes library not found'
|
||||
|
||||
|
||||
+if not salt.utils.is_windows():
|
||||
+ @contextmanager
|
||||
+ def _time_limit(seconds):
|
||||
+ def signal_handler(signum, frame):
|
||||
+ raise TimeoutException
|
||||
+ signal.signal(signal.SIGALRM, signal_handler)
|
||||
+ signal.alarm(seconds)
|
||||
+ try:
|
||||
+ yield
|
||||
+ finally:
|
||||
+ signal.alarm(0)
|
||||
+
|
||||
+ POLLING_TIME_LIMIT = 30
|
||||
+
|
||||
+
|
||||
# pylint: disable=no-member
|
||||
def _setup_conn(**kwargs):
|
||||
'''
|
||||
@@ -692,7 +711,30 @@ def delete_deployment(name, namespace='default', **kwargs):
|
||||
name=name,
|
||||
namespace=namespace,
|
||||
body=body)
|
||||
- return api_response.to_dict()
|
||||
+ mutable_api_response = api_response.to_dict()
|
||||
+ if not salt.utils.is_windows():
|
||||
+ try:
|
||||
+ with _time_limit(POLLING_TIME_LIMIT):
|
||||
+ while show_deployment(name, namespace) is not None:
|
||||
+ sleep(1)
|
||||
+ else: # pylint: disable=useless-else-on-loop
|
||||
+ mutable_api_response['code'] = 200
|
||||
+ except TimeoutException:
|
||||
+ pass
|
||||
+ else:
|
||||
+ # Windows has not signal.alarm implementation, so we are just falling
|
||||
+ # back to loop-counting.
|
||||
+ for i in range(60):
|
||||
+ if show_deployment(name, namespace) is None:
|
||||
+ mutable_api_response['code'] = 200
|
||||
+ break
|
||||
+ else:
|
||||
+ sleep(1)
|
||||
+ if mutable_api_response['code'] != 200:
|
||||
+ log.warning('Reached polling time limit. Deployment is not yet '
|
||||
+ 'deleted, but we are backing off. Sorry, but you\'ll '
|
||||
+ 'have to check manually.')
|
||||
+ return mutable_api_response
|
||||
except (ApiException, HTTPError) as exc:
|
||||
if isinstance(exc, ApiException) and exc.status == 404:
|
||||
return None
|
||||
diff --git a/tests/unit/modules/test_kubernetes.py b/tests/unit/modules/test_kubernetes.py
|
||||
new file mode 100644
|
||||
index 0000000000..493822a93c
|
||||
--- /dev/null
|
||||
+++ b/tests/unit/modules/test_kubernetes.py
|
||||
@@ -0,0 +1,126 @@
|
||||
+# -*- coding: utf-8 -*-
|
||||
+'''
|
||||
+ :codeauthor: :email:`Jochen Breuer <jbreuer@suse.de>`
|
||||
+'''
|
||||
+
|
||||
+# Import Python Libs
|
||||
+from __future__ import absolute_import
|
||||
+
|
||||
+# Import Salt Testing Libs
|
||||
+from salttesting import TestCase, skipIf
|
||||
+from salttesting.mock import (
|
||||
+ Mock,
|
||||
+ patch,
|
||||
+ NO_MOCK,
|
||||
+ NO_MOCK_REASON
|
||||
+)
|
||||
+
|
||||
+try:
|
||||
+ from salt.modules import kubernetes
|
||||
+except ImportError:
|
||||
+ kubernetes = False
|
||||
+
|
||||
+# Globals
|
||||
+kubernetes.__salt__ = dict()
|
||||
+kubernetes.__grains__ = dict()
|
||||
+kubernetes.__context__ = dict()
|
||||
+
|
||||
+
|
||||
+@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
+@skipIf(kubernetes is False, "Probably Kubernetes client lib is not installed. \
|
||||
+ Skipping test_kubernetes.py")
|
||||
+class KubernetesTestCase(TestCase):
|
||||
+ '''
|
||||
+ Test cases for salt.modules.kubernetes
|
||||
+ '''
|
||||
+
|
||||
+ def test_nodes(self):
|
||||
+ '''
|
||||
+ Test node listing.
|
||||
+ :return:
|
||||
+ '''
|
||||
+ with patch('salt.modules.kubernetes.kubernetes') as mock_kubernetes_lib:
|
||||
+ with patch.dict(kubernetes.__salt__, {'config.option': Mock(return_value="")}):
|
||||
+ mock_kubernetes_lib.client.CoreV1Api.return_value = Mock(
|
||||
+ **{"list_node.return_value.to_dict.return_value":
|
||||
+ {'items': [{'metadata': {'name': 'mock_node_name'}}]}}
|
||||
+ )
|
||||
+ self.assertEqual(kubernetes.nodes(), ['mock_node_name'])
|
||||
+ self.assertTrue(kubernetes.kubernetes.client.CoreV1Api().list_node().to_dict.called)
|
||||
+
|
||||
+ def test_deployments(self):
|
||||
+ '''
|
||||
+ Tests deployment listing.
|
||||
+ :return:
|
||||
+ '''
|
||||
+ with patch('salt.modules.kubernetes.kubernetes') as mock_kubernetes_lib:
|
||||
+ with patch.dict(kubernetes.__salt__, {'config.option': Mock(return_value="")}):
|
||||
+ mock_kubernetes_lib.client.ExtensionsV1beta1Api.return_value = Mock(
|
||||
+ **{"list_namespaced_deployment.return_value.to_dict.return_value":
|
||||
+ {'items': [{'metadata': {'name': 'mock_deployment_name'}}]}}
|
||||
+ )
|
||||
+ self.assertEqual(kubernetes.deployments(), ['mock_deployment_name'])
|
||||
+ self.assertTrue(
|
||||
+ kubernetes.kubernetes.client.ExtensionsV1beta1Api().list_namespaced_deployment().to_dict.called)
|
||||
+
|
||||
+ def test_services(self):
|
||||
+ '''
|
||||
+ Tests services listing.
|
||||
+ :return:
|
||||
+ '''
|
||||
+ with patch('salt.modules.kubernetes.kubernetes') as mock_kubernetes_lib:
|
||||
+ with patch.dict(kubernetes.__salt__, {'config.option': Mock(return_value="")}):
|
||||
+ mock_kubernetes_lib.client.CoreV1Api.return_value = Mock(
|
||||
+ **{"list_namespaced_service.return_value.to_dict.return_value":
|
||||
+ {'items': [{'metadata': {'name': 'mock_service_name'}}]}}
|
||||
+ )
|
||||
+ self.assertEqual(kubernetes.services(), ['mock_service_name'])
|
||||
+ self.assertTrue(kubernetes.kubernetes.client.CoreV1Api().list_namespaced_service().to_dict.called)
|
||||
+
|
||||
+ def test_pods(self):
|
||||
+ '''
|
||||
+ Tests pods listing.
|
||||
+ :return:
|
||||
+ '''
|
||||
+ with patch('salt.modules.kubernetes.kubernetes') as mock_kubernetes_lib:
|
||||
+ with patch.dict(kubernetes.__salt__, {'config.option': Mock(return_value="")}):
|
||||
+ mock_kubernetes_lib.client.CoreV1Api.return_value = Mock(
|
||||
+ **{"list_namespaced_pod.return_value.to_dict.return_value":
|
||||
+ {'items': [{'metadata': {'name': 'mock_pod_name'}}]}}
|
||||
+ )
|
||||
+ self.assertEqual(kubernetes.pods(), ['mock_pod_name'])
|
||||
+ self.assertTrue(kubernetes.kubernetes.client.CoreV1Api().
|
||||
+ list_namespaced_pod().to_dict.called)
|
||||
+
|
||||
+ def test_delete_deployments(self):
|
||||
+ '''
|
||||
+ Tests deployment deletion
|
||||
+ :return:
|
||||
+ '''
|
||||
+ with patch('salt.modules.kubernetes.kubernetes') as mock_kubernetes_lib:
|
||||
+ with patch('salt.modules.kubernetes.show_deployment', Mock(return_value=None)):
|
||||
+ with patch.dict(kubernetes.__salt__, {'config.option': Mock(return_value="")}):
|
||||
+ mock_kubernetes_lib.client.V1DeleteOptions = Mock(return_value="")
|
||||
+ mock_kubernetes_lib.client.ExtensionsV1beta1Api.return_value = Mock(
|
||||
+ **{"delete_namespaced_deployment.return_value.to_dict.return_value": {'code': ''}}
|
||||
+ )
|
||||
+ self.assertEqual(kubernetes.delete_deployment("test"), {'code': 200})
|
||||
+ self.assertTrue(
|
||||
+ kubernetes.kubernetes.client.ExtensionsV1beta1Api().
|
||||
+ delete_namespaced_deployment().to_dict.called)
|
||||
+
|
||||
+ def test_create_deployments(self):
|
||||
+ '''
|
||||
+ Tests deployment creation.
|
||||
+ :return:
|
||||
+ '''
|
||||
+ with patch('salt.modules.kubernetes.kubernetes') as mock_kubernetes_lib:
|
||||
+ with patch.dict(kubernetes.__salt__, {'config.option': Mock(return_value="")}):
|
||||
+ mock_kubernetes_lib.client.ExtensionsV1beta1Api.return_value = Mock(
|
||||
+ **{"create_namespaced_deployment.return_value.to_dict.return_value": {}}
|
||||
+ )
|
||||
+ self.assertEqual(kubernetes.create_deployment("test", "default", {}, {},
|
||||
+ None, None, None), {})
|
||||
+ self.assertTrue(
|
||||
+ kubernetes.kubernetes.client.ExtensionsV1beta1Api().
|
||||
+ create_namespaced_deployment().to_dict.called)
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
162
fix-for-wrong-version-processing.patch
Normal file
162
fix-for-wrong-version-processing.patch
Normal file
@ -0,0 +1,162 @@
|
||||
From 914cabfacd9c1209e3f0e7a613e8cc0d1617580b Mon Sep 17 00:00:00 2001
|
||||
From: Jochen Breuer <jbreuer@suse.de>
|
||||
Date: Mon, 11 Dec 2017 09:49:10 +0100
|
||||
Subject: [PATCH] Fix for wrong version processing
|
||||
|
||||
Since version and epoch seem to be split by default now, the yum pkg info
|
||||
processing should have changed.
|
||||
|
||||
* Fixes the version info processing for pkg installation.
|
||||
* Test for installation with and without diff_attr.
|
||||
---
|
||||
salt/modules/yumpkg.py | 28 +++++++++------
|
||||
tests/unit/modules/test_yumpkg.py | 72 +++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 90 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py
|
||||
index 8b63bff4a3..027d680bff 100644
|
||||
--- a/salt/modules/yumpkg.py
|
||||
+++ b/salt/modules/yumpkg.py
|
||||
@@ -588,7 +588,6 @@ def version_cmp(pkg1, pkg2, ignore_epoch=False):
|
||||
|
||||
salt '*' pkg.version_cmp '0.2-001' '0.2.0.1-002'
|
||||
'''
|
||||
-
|
||||
return __salt__['lowpkg.version_cmp'](pkg1, pkg2, ignore_epoch=ignore_epoch)
|
||||
|
||||
|
||||
@@ -1440,18 +1439,20 @@ def install(name=None,
|
||||
else:
|
||||
pkgstr = pkgpath
|
||||
|
||||
- # Lambda to trim the epoch from the currently-installed version if
|
||||
- # no epoch is specified in the specified version
|
||||
- norm_epoch = lambda x, y: x.split(':', 1)[-1] \
|
||||
- if ':' not in y \
|
||||
- else x
|
||||
cver = old_as_list.get(pkgname, [])
|
||||
if reinstall and cver:
|
||||
for ver in cver:
|
||||
- ver = norm_epoch(ver, version_num)
|
||||
+ if diff_attr:
|
||||
+ # Since diff_attr was provided, the version info
|
||||
+ # is a dict.
|
||||
+ ver2 = ver['version']
|
||||
+ else:
|
||||
+ # No diff_attr was provided, so version is directly
|
||||
+ # in ver.
|
||||
+ ver2 = ver
|
||||
if salt.utils.compare_versions(ver1=version_num,
|
||||
oper='==',
|
||||
- ver2=ver,
|
||||
+ ver2=ver2,
|
||||
cmp_func=version_cmp):
|
||||
# This version is already installed, so we need to
|
||||
# reinstall.
|
||||
@@ -1462,10 +1463,17 @@ def install(name=None,
|
||||
to_install.append((pkgname, pkgstr))
|
||||
else:
|
||||
for ver in cver:
|
||||
- ver = norm_epoch(ver, version_num)
|
||||
+ if diff_attr:
|
||||
+ # Since diff_attr was provided, the version info
|
||||
+ # is a dict.
|
||||
+ ver2 = ver['version']
|
||||
+ else:
|
||||
+ # No diff_attr was provided, so version is directly
|
||||
+ # in ver.
|
||||
+ ver2 = ver
|
||||
if salt.utils.compare_versions(ver1=version_num,
|
||||
oper='>=',
|
||||
- ver2=ver,
|
||||
+ ver2=ver2,
|
||||
cmp_func=version_cmp):
|
||||
to_install.append((pkgname, pkgstr))
|
||||
break
|
||||
diff --git a/tests/unit/modules/test_yumpkg.py b/tests/unit/modules/test_yumpkg.py
|
||||
index cf754d6289..c5e8d746d5 100644
|
||||
--- a/tests/unit/modules/test_yumpkg.py
|
||||
+++ b/tests/unit/modules/test_yumpkg.py
|
||||
@@ -27,6 +27,78 @@ class YumTestCase(TestCase, LoaderModuleMockMixin):
|
||||
def setup_loader_modules(self):
|
||||
return {yumpkg: {'rpm': None}}
|
||||
|
||||
+ def test_install_pkg(self):
|
||||
+ '''
|
||||
+ Test package installation.
|
||||
+
|
||||
+ :return:
|
||||
+ '''
|
||||
+ def _add_data(data, key, value):
|
||||
+ data.setdefault(key, []).append(value)
|
||||
+
|
||||
+ rpm_out = [
|
||||
+ 'python-urlgrabber_|-(none)_|-3.10_|-8.el7_|-noarch_|-(none)_|-1487838471',
|
||||
+ 'alsa-lib_|-(none)_|-1.1.1_|-1.el7_|-x86_64_|-(none)_|-1487838475',
|
||||
+ 'gnupg2_|-(none)_|-2.0.22_|-4.el7_|-x86_64_|-(none)_|-1487838477',
|
||||
+ 'rpm-python_|-(none)_|-4.11.3_|-21.el7_|-x86_64_|-(none)_|-1487838477',
|
||||
+ 'pygpgme_|-(none)_|-0.3_|-9.el7_|-x86_64_|-(none)_|-1487838478',
|
||||
+ 'yum_|-(none)_|-3.4.3_|-150.el7.centos_|-noarch_|-(none)_|-1487838479',
|
||||
+ 'lzo_|-(none)_|-2.06_|-8.el7_|-x86_64_|-(none)_|-1487838479',
|
||||
+ 'qrencode-libs_|-(none)_|-3.4.1_|-3.el7_|-x86_64_|-(none)_|-1487838480',
|
||||
+ 'ustr_|-(none)_|-1.0.4_|-16.el7_|-x86_64_|-(none)_|-1487838480',
|
||||
+ 'shadow-utils_|-2_|-4.1.5.1_|-24.el7_|-x86_64_|-(none)_|-1487838481',
|
||||
+ 'util-linux_|-(none)_|-2.23.2_|-33.el7_|-x86_64_|-(none)_|-1487838484',
|
||||
+ 'openssh_|-(none)_|-6.6.1p1_|-33.el7_3_|-x86_64_|-(none)_|-1487838485',
|
||||
+ 'virt-what_|-(none)_|-1.13_|-8.el7_|-x86_64_|-(none)_|-1487838486',
|
||||
+ ]
|
||||
+ with patch.dict(yumpkg.__grains__, {'osarch': 'x86_64', 'os': 'RedHat'}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'cmd.run': MagicMock(return_value=os.linesep.join(rpm_out))}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'cmd.run_all': MagicMock(return_value={'retcode': 0})}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'pkg_resource.add_pkg': _add_data}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'pkg_resource.parse_targets': MagicMock(return_value=({'python-urlgrabber': '0.0.1'} , 'repository'))}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'pkg_resource.format_pkg_list': pkg_resource.format_pkg_list}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'config.get': MagicMock()}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'lowpkg.version_cmp': MagicMock(return_value=-1)}):
|
||||
+ pkgs = yumpkg.install(name='python-urlgrabber')
|
||||
+ self.assertEqual(pkgs, {})
|
||||
+
|
||||
+
|
||||
+ def test_install_pkg_with_diff_attr(self):
|
||||
+ '''
|
||||
+ Test package installation with diff_attr.
|
||||
+
|
||||
+ :return:
|
||||
+ '''
|
||||
+ def _add_data(data, key, value):
|
||||
+ data.setdefault(key, []).append(value)
|
||||
+
|
||||
+ rpm_out = [
|
||||
+ 'python-urlgrabber_|-(none)_|-3.10_|-8.el7_|-noarch_|-(none)_|-1487838471',
|
||||
+ 'alsa-lib_|-(none)_|-1.1.1_|-1.el7_|-x86_64_|-(none)_|-1487838475',
|
||||
+ 'gnupg2_|-(none)_|-2.0.22_|-4.el7_|-x86_64_|-(none)_|-1487838477',
|
||||
+ 'rpm-python_|-(none)_|-4.11.3_|-21.el7_|-x86_64_|-(none)_|-1487838477',
|
||||
+ 'pygpgme_|-(none)_|-0.3_|-9.el7_|-x86_64_|-(none)_|-1487838478',
|
||||
+ 'yum_|-(none)_|-3.4.3_|-150.el7.centos_|-noarch_|-(none)_|-1487838479',
|
||||
+ 'lzo_|-(none)_|-2.06_|-8.el7_|-x86_64_|-(none)_|-1487838479',
|
||||
+ 'qrencode-libs_|-(none)_|-3.4.1_|-3.el7_|-x86_64_|-(none)_|-1487838480',
|
||||
+ 'ustr_|-(none)_|-1.0.4_|-16.el7_|-x86_64_|-(none)_|-1487838480',
|
||||
+ 'shadow-utils_|-2_|-4.1.5.1_|-24.el7_|-x86_64_|-(none)_|-1487838481',
|
||||
+ 'util-linux_|-(none)_|-2.23.2_|-33.el7_|-x86_64_|-(none)_|-1487838484',
|
||||
+ 'openssh_|-(none)_|-6.6.1p1_|-33.el7_3_|-x86_64_|-(none)_|-1487838485',
|
||||
+ 'virt-what_|-(none)_|-1.13_|-8.el7_|-x86_64_|-(none)_|-1487838486',
|
||||
+ ]
|
||||
+ with patch.dict(yumpkg.__grains__, {'osarch': 'x86_64', 'os': 'RedHat'}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'cmd.run': MagicMock(return_value=os.linesep.join(rpm_out))}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'cmd.run_all': MagicMock(return_value={'retcode': 0})}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'pkg_resource.add_pkg': _add_data}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'pkg_resource.parse_targets': MagicMock(return_value=({'python-urlgrabber': '0.0.1'} , 'repository'))}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'pkg_resource.format_pkg_list': pkg_resource.format_pkg_list}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'config.get': MagicMock()}), \
|
||||
+ patch.dict(yumpkg.__salt__, {'lowpkg.version_cmp': MagicMock(return_value=-1)}):
|
||||
+ pkgs = yumpkg.install(name='python-urlgrabber', diff_attr=['version', 'epoch', 'release', 'arch'])
|
||||
+ self.assertEqual(pkgs, {})
|
||||
+
|
||||
+
|
||||
def test_list_pkgs(self):
|
||||
'''
|
||||
Test packages listing.
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
26
fix-salt-master-for-old-psutil.patch
Normal file
26
fix-salt-master-for-old-psutil.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From e9635560f2b0a213518c5023e0b6fb4a11e5570d Mon Sep 17 00:00:00 2001
|
||||
From: Mihai Dinca <mdinca@suse.de>
|
||||
Date: Fri, 8 Dec 2017 13:34:06 +0100
|
||||
Subject: [PATCH] Fix salt-master for old psutil
|
||||
|
||||
---
|
||||
salt/utils/psutil_compat.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/salt/utils/psutil_compat.py b/salt/utils/psutil_compat.py
|
||||
index a32712860a..dee563455b 100644
|
||||
--- a/salt/utils/psutil_compat.py
|
||||
+++ b/salt/utils/psutil_compat.py
|
||||
@@ -26,7 +26,7 @@ else:
|
||||
# Psuedo "from psutil import *"
|
||||
_globals = globals()
|
||||
for attr in psutil.__all__:
|
||||
- _temp = __import__('psutil', globals(), locals(), [attr], -1)
|
||||
+ _temp = __import__('psutil', globals(), locals(), [attr], -1 if six.PY2 else 0)
|
||||
try:
|
||||
_globals[attr] = getattr(_temp, attr)
|
||||
except AttributeError:
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4033a19f562875d4124d5f18fffb485cbbb1a256996b4a8019ac4f32064657be
|
||||
size 6413238
|
||||
oid sha256:6b82846ed4005af7655290cd9bdc62c1d4912d4809acaca2ff37ebff0960b18c
|
||||
size 1250836
|
||||
|
@ -1,7 +1,7 @@
|
||||
From cb472e1f0fc18a554e0de9e3fe6bbe16557957ee Mon Sep 17 00:00:00 2001
|
||||
From: Silvio Moioli <smoioli@suse.de>
|
||||
Date: Wed, 20 Sep 2017 14:33:33 +0200
|
||||
Subject: [PATCH 4/6] Introduce process_count_max minion configuration
|
||||
Subject: [PATCH] Introduce process_count_max minion configuration
|
||||
parameter
|
||||
|
||||
This allows users to limit the number of processes or threads a minion
|
||||
@ -206,5 +206,6 @@ index 535dfeedfc..6c9dca13cd 100644
|
||||
+ finally:
|
||||
+ minion.destroy()
|
||||
--
|
||||
2.14.2
|
||||
2.15.1
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
From ca7031e5223bb3bd35c31211d29177f05ed5e304 Mon Sep 17 00:00:00 2001
|
||||
From: Silvio Moioli <smoioli@suse.de>
|
||||
Date: Thu, 13 Jul 2017 15:59:01 +0200
|
||||
Subject: [PATCH 1/6] list_pkgs: add parameter for returned attribute selection
|
||||
(bsc#1052264)
|
||||
Subject: [PATCH] list_pkgs: add parameter for returned attribute
|
||||
selection (bsc#1052264)
|
||||
|
||||
zypper.list_pkgs:
|
||||
* It adds a new optional parameter to list_pkg in the zypper module to return more data than the version (original reason is that for SUSE Manager integration we also need arch and install_date). Format is the same of existing method info_installed.
|
||||
@ -787,5 +787,6 @@ index f3403e6e1c..41f3845646 100644
|
||||
def test_list_patches(self):
|
||||
'''
|
||||
--
|
||||
2.14.2
|
||||
2.15.1
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 461654496d36a264903057a8255aec4eb700e506 Mon Sep 17 00:00:00 2001
|
||||
From: Silvio Moioli <smoioli@suse.de>
|
||||
Date: Wed, 20 Sep 2017 14:32:47 +0200
|
||||
Subject: [PATCH 3/6] multiprocessing minion option: documentation fixes
|
||||
Subject: [PATCH] multiprocessing minion option: documentation fixes
|
||||
|
||||
---
|
||||
doc/man/salt.7 | 1 +
|
||||
@ -42,5 +42,6 @@ index e0f349931c..5c92b932ab 100644
|
||||
|
||||
|
||||
--
|
||||
2.14.2
|
||||
2.15.1
|
||||
|
||||
|
||||
|
25
older-logrotate-need-su-directive.patch
Normal file
25
older-logrotate-need-su-directive.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From d68365a35dd00cced7cdc6eff2ad8a3b823c26f6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Calmer <mc@suse.de>
|
||||
Date: Thu, 7 Dec 2017 17:30:31 +0100
|
||||
Subject: [PATCH] older logrotate need su directive
|
||||
|
||||
---
|
||||
pkg/suse/salt-common.logrotate | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/pkg/suse/salt-common.logrotate b/pkg/suse/salt-common.logrotate
|
||||
index 0d99d1b801..625670942c 100644
|
||||
--- a/pkg/suse/salt-common.logrotate
|
||||
+++ b/pkg/suse/salt-common.logrotate
|
||||
@@ -8,6 +8,7 @@
|
||||
}
|
||||
|
||||
/var/log/salt/minion {
|
||||
+ su root root
|
||||
weekly
|
||||
missingok
|
||||
rotate 7
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
25
python3-compatibility-fix-got-bytes-instead-of-strin.patch
Normal file
25
python3-compatibility-fix-got-bytes-instead-of-strin.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From d21ea1062f1cd8da0e604288b369c7ff38919c78 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Calmer <mc@suse.de>
|
||||
Date: Tue, 19 Dec 2017 17:07:19 +0100
|
||||
Subject: [PATCH] python3 compatibility fix - got bytes instead of string
|
||||
|
||||
---
|
||||
salt/netapi/rest_cherrypy/tools/websockets.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/salt/netapi/rest_cherrypy/tools/websockets.py b/salt/netapi/rest_cherrypy/tools/websockets.py
|
||||
index fe4f9def85..44c5e2fa05 100644
|
||||
--- a/salt/netapi/rest_cherrypy/tools/websockets.py
|
||||
+++ b/salt/netapi/rest_cherrypy/tools/websockets.py
|
||||
@@ -54,6 +54,6 @@ class SynchronizingWebsocket(WebSocket):
|
||||
This ensures completion of the underlying websocket connection
|
||||
and can be used to synchronize parallel senders.
|
||||
'''
|
||||
- if message.data == 'websocket client ready':
|
||||
+ if message.data.decode('utf-8') == 'websocket client ready':
|
||||
self.pipe.send(message)
|
||||
self.send('server received message', False)
|
||||
--
|
||||
2.13.6
|
||||
|
||||
|
123
return-error-when-gid_from_name-and-group-does-not-e.patch
Normal file
123
return-error-when-gid_from_name-and-group-does-not-e.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 5384cb815764af43f287bcb6ed49a9a68d5cd5c0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
|
||||
<psuarezhernandez@suse.com>
|
||||
Date: Wed, 10 Jan 2018 11:59:33 +0000
|
||||
Subject: [PATCH] Return error when gid_from_name and group does not
|
||||
exist.
|
||||
|
||||
Fixes #45345
|
||||
|
||||
Ensure empty string gid is set to None
|
||||
|
||||
Make pylint happy
|
||||
|
||||
Fix integration tests for 'user.present' state.
|
||||
|
||||
Update documentation for 'gid_from_name' parameter
|
||||
|
||||
Refactor to prevent logical bug when gid is 0
|
||||
---
|
||||
salt/states/user.py | 7 +++++-
|
||||
tests/integration/states/test_user.py | 42 +++++++++++++++++++++++------------
|
||||
2 files changed, 34 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/salt/states/user.py b/salt/states/user.py
|
||||
index 8a731cc2a1..737c39f4b4 100644
|
||||
--- a/salt/states/user.py
|
||||
+++ b/salt/states/user.py
|
||||
@@ -240,7 +240,8 @@ def present(name,
|
||||
|
||||
gid_from_name
|
||||
If True, the default group id will be set to the id of the group with
|
||||
- the same name as the user, Default is ``False``.
|
||||
+ the same name as the user. If the group does not exist the state will
|
||||
+ fail. Default is ``False``.
|
||||
|
||||
groups
|
||||
A list of groups to assign the user to, pass a list object. If a group
|
||||
@@ -455,6 +456,10 @@ def present(name,
|
||||
|
||||
if gid_from_name:
|
||||
gid = __salt__['file.group_to_gid'](name)
|
||||
+ if gid == '':
|
||||
+ ret['comment'] = 'Default group with name "{0}" is not present'.format(name)
|
||||
+ ret['result'] = False
|
||||
+ return ret
|
||||
|
||||
changes = _changes(name,
|
||||
uid,
|
||||
diff --git a/tests/integration/states/test_user.py b/tests/integration/states/test_user.py
|
||||
index 1317f12f97..ae9774a241 100644
|
||||
--- a/tests/integration/states/test_user.py
|
||||
+++ b/tests/integration/states/test_user.py
|
||||
@@ -97,15 +97,25 @@ class UserTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
home=HOMEDIR)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
|
||||
- def test_user_present_nondefault(self):
|
||||
+ @requires_system_grains
|
||||
+ def test_user_present_nondefault(self, grains=None):
|
||||
'''
|
||||
This is a DESTRUCTIVE TEST it creates a new user on the on the minion.
|
||||
'''
|
||||
ret = self.run_state('user.present', name=self.user_name,
|
||||
home=self.user_home)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
+ ret = self.run_function('user.info', [self.user_name])
|
||||
+ self.assertReturnNonEmptySaltType(ret)
|
||||
+ group_name = grp.getgrgid(ret['gid']).gr_name
|
||||
if not salt.utils.is_darwin():
|
||||
self.assertTrue(os.path.isdir(self.user_home))
|
||||
+ if grains['os_family'] in ('Suse',):
|
||||
+ self.assertEqual(group_name, 'users')
|
||||
+ elif grains['os_family'] == 'MacOS':
|
||||
+ self.assertEqual(group_name, 'staff')
|
||||
+ else:
|
||||
+ self.assertEqual(group_name, self.user_name)
|
||||
|
||||
@requires_system_grains
|
||||
def test_user_present_gid_from_name_default(self, grains=None):
|
||||
@@ -120,22 +130,26 @@ class UserTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
# user
|
||||
gid_from_name = False if grains['os_family'] == 'MacOS' else True
|
||||
|
||||
- ret = self.run_state('user.present', name=self.user_name,
|
||||
+ ret_user_present = self.run_state('user.present', name=self.user_name,
|
||||
gid_from_name=gid_from_name, home=self.user_home)
|
||||
- self.assertSaltTrueReturn(ret)
|
||||
|
||||
- ret = self.run_function('user.info', [self.user_name])
|
||||
- self.assertReturnNonEmptySaltType(ret)
|
||||
- group_name = grp.getgrgid(ret['gid']).gr_name
|
||||
-
|
||||
- if not salt.utils.is_darwin():
|
||||
- self.assertTrue(os.path.isdir(self.user_home))
|
||||
- if grains['os_family'] in ('Suse',):
|
||||
- self.assertEqual(group_name, 'users')
|
||||
- elif grains['os_family'] == 'MacOS':
|
||||
- self.assertEqual(group_name, 'staff')
|
||||
+ if gid_from_name:
|
||||
+ self.assertSaltFalseReturn(ret_user_present)
|
||||
+ ret_user_present = ret_user_present[next(iter(ret_user_present))]
|
||||
+ self.assertTrue('is not present' in ret_user_present['comment'])
|
||||
else:
|
||||
- self.assertEqual(group_name, self.user_name)
|
||||
+ self.assertSaltTrueReturn(ret_user_present)
|
||||
+ ret_user_info = self.run_function('user.info', [self.user_name])
|
||||
+ self.assertReturnNonEmptySaltType(ret_user_info)
|
||||
+ group_name = grp.getgrgid(ret_user_info['gid']).gr_name
|
||||
+ if not salt.utils.is_darwin():
|
||||
+ self.assertTrue(os.path.isdir(self.user_home))
|
||||
+ if grains['os_family'] in ('Suse',):
|
||||
+ self.assertEqual(group_name, 'users')
|
||||
+ elif grains['os_family'] == 'MacOS':
|
||||
+ self.assertEqual(group_name, 'staff')
|
||||
+ else:
|
||||
+ self.assertEqual(group_name, self.user_name)
|
||||
|
||||
def test_user_present_gid_from_name(self):
|
||||
'''
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 8f81bee8d8929cc4cd30dabc7cbc92d2cba9760e Mon Sep 17 00:00:00 2001
|
||||
From: Christian Lanig <clanig@suse.com>
|
||||
Date: Mon, 27 Nov 2017 13:10:26 +0100
|
||||
Subject: [PATCH 2/2] Run salt-api as user salt (bsc#1064520)
|
||||
Subject: [PATCH] Run salt-api as user salt (bsc#1064520)
|
||||
|
||||
---
|
||||
pkg/salt-api.service | 1 +
|
||||
@ -20,5 +20,6 @@ index 7ca582dfb4..bf513e4dbd 100644
|
||||
ExecStart=/usr/bin/salt-api
|
||||
TimeoutStopSec=3
|
||||
--
|
||||
2.14.2
|
||||
2.15.1
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 3902fe4183d169808b9d248b9b963926035ba954 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= <kkaempf@suse.de>
|
||||
Date: Wed, 20 Jan 2016 11:01:06 +0100
|
||||
Subject: [PATCH 1/2] Run salt master as dedicated salt user
|
||||
Subject: [PATCH] Run salt master as dedicated salt user
|
||||
|
||||
* Minion runs always as a root
|
||||
---
|
||||
@ -42,5 +42,6 @@ index 3cd002308e..0d99d1b801 100644
|
||||
missingok
|
||||
rotate 7
|
||||
--
|
||||
2.14.2
|
||||
2.15.1
|
||||
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ff3bc7de5abf01b8acbd144db5811b00867179b2353f5c6f7f19241e2eff2840
|
||||
size 11471191
|
124
salt.changes
124
salt.changes
@ -1,3 +1,127 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 25 13:04:24 UTC 2018 - pablo.suarezhernandez@suse.com
|
||||
|
||||
- Fix the usage of custom macros on the spec file.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 25 10:49:53 UTC 2018 - bmaryniuk@suse.com
|
||||
|
||||
- Fix RES7: different dependency names for python-PyYAML
|
||||
and python-MarkupSafe
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jan 24 15:04:42 UTC 2018 - bmaryniuk@suse.com
|
||||
|
||||
- Build both python2 and python3 binaries together.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jan 17 11:26:54 UTC 2018 - pablo.suarezhernandez@suse.com
|
||||
|
||||
- Bugfix: errors in external pillar causes crash instead of report
|
||||
of them (bsc#1068446)
|
||||
- Fix 'user.present' when 'gid_from_name' is set but group does
|
||||
not exist.
|
||||
|
||||
- Added:
|
||||
* bugfix-the-logic-according-to-the-exact-described-pu.patch
|
||||
* return-error-when-gid_from_name-and-group-does-not-e.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 11 15:57:11 UTC 2018 - jrenner@suse.com
|
||||
|
||||
- Fix "No service execution module loaded" issue (bsc#1065792)
|
||||
- Set SHELL environment variable
|
||||
|
||||
Added:
|
||||
* fix-bsc-1065792.patch
|
||||
* set-shell-environment-variable-64.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 05 15:24:30 UTC 2018 - jbreuer@suse.de
|
||||
|
||||
- Removed unnecessary logging on shutdown (bsc#1050003)
|
||||
- Renamed patch that adds grain fqdns
|
||||
|
||||
Changed:
|
||||
* catching-error-when-pidfile-cannot-be-deleted
|
||||
|
||||
Removed:
|
||||
* fix-for-pidfile-removal-logging
|
||||
|
||||
Renamed:
|
||||
* add-fqdns-grains -> feat-add-grain-for-all-fqdns
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Dec 28 10:37:10 UTC 2017 - michele.bologna@suse.com
|
||||
|
||||
- Add fqdns to grains (bsc#1063419)
|
||||
Added:
|
||||
* add-fqdns-grains.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Dec 19 16:15:14 UTC 2017 - mc@suse.com
|
||||
|
||||
- Fixing cherrypy websocket with python3
|
||||
Added:
|
||||
* python3-compatibility-fix-got-bytes-instead-of-strin.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Dec 18 15:28:26 UTC 2017 - mihai.dinca@suse.com
|
||||
|
||||
- Various-bug-fixes
|
||||
- Python3 bugfix for cherrypy read()
|
||||
- Fix for logging on salt-master exit in rare cases (pid-file removal)
|
||||
- Added:
|
||||
* cherrypy-read-reads-bytes-from-the-wire-and-write-th.patch
|
||||
* fix-for-pidfile-removal-logging.patch
|
||||
* split-only-strings-if-they-are-such.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Dec 14 09:18:02 UTC 2017 - mihai.dinca@suse.com
|
||||
|
||||
- Fix salt-master for old psutil version
|
||||
- Added:
|
||||
* fix-salt-master-for-old-psutil.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Dec 13 16:23:38 UTC 2017 - mihai.dinca@suse.com
|
||||
|
||||
- Put back accidentally removed patches
|
||||
- Added:
|
||||
* avoid-excessive-syslogging-by-watchdog-cronjob-58.patch
|
||||
* catching-error-when-pidfile-cannot-be-deleted.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Dec 13 16:22:25 UTC 2017 - mihai.dinca@suse.com
|
||||
|
||||
- Fix for delete_deployment in Kubernetes module (bsc#1059291)
|
||||
|
||||
- Added:
|
||||
* fix-for-delete_deployment-in-kubernetes-module.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Dec 13 16:15:53 UTC 2017 - mihai.dinca@suse.com
|
||||
|
||||
- Older logrotate need su directive
|
||||
* Added:
|
||||
older-logrotate-need-su-directive.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Dec 13 16:10:32 UTC 2017 - mihai.dinca@suse.com
|
||||
|
||||
- Fix bsc#1041993 already included in 2017.7.2
|
||||
- Removed:
|
||||
* removes-beacon-configuration-deprecation-warning-48.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Dec 13 16:09:41 UTC 2017 - mihai.dinca@suse.com
|
||||
|
||||
- Fixed beacons failure when pillar-based suppressing config-based.
|
||||
(bsc#1060230)
|
||||
|
||||
- Added:
|
||||
* activate-all-beacons-sources-config-pillar-grains.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Dec 7 11:19:12 UTC 2017 - dimstar@opensuse.org
|
||||
|
||||
|
369
salt.spec
369
salt.spec
@ -15,6 +15,22 @@
|
||||
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
||||
#
|
||||
|
||||
%if 0%{?suse_version} >= 1320
|
||||
# SLE15
|
||||
%global build_py3 1
|
||||
%global build_py2 1
|
||||
%global default_py3 1
|
||||
%else
|
||||
%if 0%{?suse_version} == 1315
|
||||
# SLE12
|
||||
%global build_py3 1
|
||||
%global build_py2 1
|
||||
%else
|
||||
# RES7
|
||||
%global build_py2 1
|
||||
%endif
|
||||
%endif
|
||||
%define pythonX %{?default_py3: python3}%{!?default_py3: python2}
|
||||
|
||||
%if 0%{?suse_version} > 1210 || 0%{?rhel} >= 7 || 0%{?fedora}
|
||||
%bcond_without systemd
|
||||
@ -42,26 +58,196 @@ Summary: A parallel remote execution system
|
||||
License: Apache-2.0
|
||||
Group: System/Management
|
||||
Url: http://saltstack.org/
|
||||
# Git: https://github.com/openSUSE/salt.git
|
||||
Source0: salt-2017.7.2.tar.gz
|
||||
Source: https://github.com/saltstack/salt/archive/v%{version}.tar.gz
|
||||
Source1: README.SUSE
|
||||
Source2: salt-tmpfiles.d
|
||||
Source3: html.tar.bz2
|
||||
Source4: update-documentation.sh
|
||||
Source5: travis.yml
|
||||
Source6: zyppnotify
|
||||
|
||||
Patch1: list_pkgs-add-parameter-for-returned-attribute-selec.patch
|
||||
Patch2: use-home-to-get-the-user-home-directory-instead-usin.patch
|
||||
Patch3: multiprocessing-minion-option-documentation-fixes.patch
|
||||
Patch4: introduce-process_count_max-minion-configuration-par.patch
|
||||
Patch5: bugfix-always-return-a-string-list-on-unknown-job-ta.patch
|
||||
Patch6: enable-with-salt-version-parameter-for-setup.py-scri.patch
|
||||
Patch7: run-salt-master-as-dedicated-salt-user.patch
|
||||
Patch8: run-salt-api-as-user-salt-bsc-1064520.patch
|
||||
Patch1: list_pkgs-add-parameter-for-returned-attribute-selec.patch
|
||||
Patch2: use-home-to-get-the-user-home-directory-instead-usin.patch
|
||||
Patch3: multiprocessing-minion-option-documentation-fixes.patch
|
||||
Patch4: introduce-process_count_max-minion-configuration-par.patch
|
||||
Patch5: bugfix-always-return-a-string-list-on-unknown-job-ta.patch
|
||||
Patch6: enable-with-salt-version-parameter-for-setup.py-scri.patch
|
||||
Patch7: run-salt-master-as-dedicated-salt-user.patch
|
||||
Patch8: run-salt-api-as-user-salt-bsc-1064520.patch
|
||||
Patch9: activate-all-beacons-sources-config-pillar-grains.patch
|
||||
Patch10: fix-for-delete_deployment-in-kubernetes-module.patch
|
||||
Patch11: catching-error-when-pidfile-cannot-be-deleted.patch
|
||||
Patch12: avoid-excessive-syslogging-by-watchdog-cronjob-58.patch
|
||||
Patch13: fix-for-wrong-version-processing.patch
|
||||
Patch14: older-logrotate-need-su-directive.patch
|
||||
Patch15: fix-salt-master-for-old-psutil.patch
|
||||
Patch16: split-only-strings-if-they-are-such.patch
|
||||
Patch17: cherrypy-read-reads-bytes-from-the-wire-and-write-th.patch
|
||||
Patch19: python3-compatibility-fix-got-bytes-instead-of-strin.patch
|
||||
Patch20: feat-add-grain-for-all-fqdns.patch
|
||||
Patch21: fix-bsc-1065792.patch
|
||||
Patch22: set-shell-environment-variable-64.patch
|
||||
Patch23: bugfix-the-logic-according-to-the-exact-described-pu.patch
|
||||
Patch24: return-error-when-gid_from_name-and-group-does-not-e.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
BuildRequires: logrotate
|
||||
%if 0%{?suse_version} > 1020
|
||||
BuildRequires: fdupes
|
||||
%endif
|
||||
|
||||
Requires: %{pythonX}-%{name} = %{version}-%{release}
|
||||
|
||||
Requires(pre): %{_sbindir}/groupadd
|
||||
Requires(pre): %{_sbindir}/useradd
|
||||
|
||||
%if 0%{?suse_version}
|
||||
Requires(pre): %fillup_prereq
|
||||
Requires(pre): pwdutils
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version}
|
||||
Requires(pre): dbus-1
|
||||
%else
|
||||
Requires(pre): dbus
|
||||
%endif
|
||||
|
||||
Requires: logrotate
|
||||
Requires: procps
|
||||
|
||||
%if %{with systemd}
|
||||
BuildRequires: systemd
|
||||
%{?systemd_requires}
|
||||
%else
|
||||
%if 0%{?suse_version}
|
||||
Requires(pre): %insserv_prereq
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%if %{with fish_completion}
|
||||
%define fish_dir %{_datadir}/fish/
|
||||
%define fish_completions_dir %{_datadir}/fish/completions/
|
||||
%endif
|
||||
|
||||
%if %{with bash_completion}
|
||||
%if 0%{?suse_version} >= 1140
|
||||
BuildRequires: bash-completion
|
||||
%else
|
||||
BuildRequires: bash
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%if %{with zsh_completion}
|
||||
BuildRequires: zsh
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel}
|
||||
BuildRequires: yum
|
||||
%endif
|
||||
|
||||
%description
|
||||
Salt is a distributed remote execution system used to execute commands and
|
||||
query data. It was developed in order to bring the best solutions found in
|
||||
the world of remote execution together and make them better, faster and more
|
||||
malleable. Salt accomplishes this via its ability to handle larger loads of
|
||||
information, and not just dozens, but hundreds or even thousands of individual
|
||||
servers, handle them quickly and through a simple and manageable interface.
|
||||
|
||||
%if 0%{?build_py2}
|
||||
%package -n python2-salt
|
||||
Summary: python2 library for salt
|
||||
Group: System/Management
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
BuildRequires: python >= 2.7
|
||||
BuildRequires: python-devel >= 2.7
|
||||
# requirements/base.txt
|
||||
%if 0%{?rhel}
|
||||
BuildRequires: python-jinja2
|
||||
BuildRequires: python-yaml
|
||||
BuildRequires: python-markupsafe
|
||||
%else
|
||||
BuildRequires: python-Jinja2
|
||||
BuildRequires: python-PyYAML
|
||||
BuildRequires: python-MarkupSafe
|
||||
%endif
|
||||
|
||||
BuildRequires: python-futures >= 2.0
|
||||
BuildRequires: python-msgpack-python > 0.3
|
||||
BuildRequires: python-psutil
|
||||
BuildRequires: python-requests >= 1.0.0
|
||||
BuildRequires: python-tornado >= 4.2.1
|
||||
|
||||
# requirements/zeromq.txt
|
||||
BuildRequires: python-pycrypto >= 2.6.1
|
||||
BuildRequires: python-pyzmq >= 2.2.0
|
||||
%if %{with test}
|
||||
# requirements/dev_python27.txt
|
||||
BuildRequires: python-boto >= 2.32.1
|
||||
BuildRequires: python-mock
|
||||
BuildRequires: python-moto >= 0.3.6
|
||||
BuildRequires: python-pip
|
||||
BuildRequires: python-salt-testing >= 2015.2.16
|
||||
BuildRequires: python-unittest2
|
||||
BuildRequires: python-xml
|
||||
%endif
|
||||
%if %{with builddocs}
|
||||
BuildRequires: python-sphinx
|
||||
%endif
|
||||
Requires: python >= 2.7
|
||||
#
|
||||
%if ! 0%{?suse_version} > 1110
|
||||
Requires: python-certifi
|
||||
%endif
|
||||
# requirements/base.txt
|
||||
%if 0%{?rhel}
|
||||
Requires: python-jinja2
|
||||
Requires: python-yaml
|
||||
Requires: python-markupsafe
|
||||
Requires: yum
|
||||
%if 0%{?rhel} == 6
|
||||
Requires: yum-plugin-security
|
||||
%endif
|
||||
%else
|
||||
Requires: python-Jinja2
|
||||
Requires: python-PyYAML
|
||||
Requires: python-MarkupSafe
|
||||
%endif
|
||||
|
||||
Requires: python-futures >= 2.0
|
||||
Requires: python-msgpack-python > 0.3
|
||||
Requires: python-psutil
|
||||
Requires: python-requests >= 1.0.0
|
||||
Requires: python-tornado >= 4.2.1
|
||||
%if 0%{?suse_version}
|
||||
# required for zypper.py
|
||||
Requires: rpm-python
|
||||
Requires(pre): libzypp(plugin:system) >= 0
|
||||
Requires: zypp-plugin-python
|
||||
# requirements/opt.txt (not all)
|
||||
# Suggests: python-MySQL-python ## Disabled for now, originally Recommended
|
||||
Suggests: python-timelib
|
||||
Suggests: python-gnupg
|
||||
# requirements/zeromq.txt
|
||||
%endif
|
||||
Requires: python-pycrypto >= 2.6.1
|
||||
Requires: python-pyzmq >= 2.2.0
|
||||
#
|
||||
%if 0%{?suse_version}
|
||||
# python-xml is part of python-base in all rhel versions
|
||||
Requires: python-xml
|
||||
Suggests: python-Mako
|
||||
Recommends: python-netaddr
|
||||
%endif
|
||||
|
||||
%description -n python2-salt
|
||||
Python2 specific files for salt
|
||||
|
||||
%endif
|
||||
|
||||
%if 0%{?build_py3}
|
||||
%package -n python3-salt
|
||||
Summary: python3 library for salt
|
||||
Group: System/Management
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
BuildRequires: python-rpm-macros
|
||||
BuildRequires: python3
|
||||
BuildRequires: python3-devel
|
||||
@ -94,26 +280,6 @@ BuildRequires: python3-xml
|
||||
%if %{with builddocs}
|
||||
BuildRequires: python3-sphinx
|
||||
%endif
|
||||
%if 0%{?suse_version} > 1020
|
||||
BuildRequires: fdupes
|
||||
%endif
|
||||
|
||||
Requires(pre): %{_sbindir}/groupadd
|
||||
Requires(pre): %{_sbindir}/useradd
|
||||
|
||||
%if 0%{?suse_version}
|
||||
Requires(pre): %fillup_prereq
|
||||
Requires(pre): pwdutils
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version}
|
||||
Requires(pre): dbus-1
|
||||
%else
|
||||
Requires(pre): dbus
|
||||
%endif
|
||||
|
||||
Requires: logrotate
|
||||
Requires: procps
|
||||
Requires: python3
|
||||
#
|
||||
%if ! 0%{?suse_version} > 1110
|
||||
@ -156,50 +322,21 @@ Suggests: python3-Mako
|
||||
Recommends: python3-netaddr
|
||||
%endif
|
||||
|
||||
%if %{with systemd}
|
||||
BuildRequires: systemd
|
||||
%{?systemd_requires}
|
||||
%else
|
||||
%if 0%{?suse_version}
|
||||
Requires(pre): %insserv_prereq
|
||||
%endif
|
||||
%endif
|
||||
%description -n python3-salt
|
||||
Python3 specific files for salt
|
||||
|
||||
%if %{with fish_completion}
|
||||
%define fish_dir %{_datadir}/fish/
|
||||
%define fish_completions_dir %{_datadir}/fish/completions/
|
||||
%endif
|
||||
|
||||
%if %{with bash_completion}
|
||||
%if 0%{?suse_version} >= 1140
|
||||
BuildRequires: bash-completion
|
||||
%else
|
||||
BuildRequires: bash
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%if %{with zsh_completion}
|
||||
BuildRequires: zsh
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel}
|
||||
BuildRequires: yum
|
||||
%endif
|
||||
|
||||
%description
|
||||
Salt is a distributed remote execution system used to execute commands and
|
||||
query data. It was developed in order to bring the best solutions found in
|
||||
the world of remote execution together and make them better, faster and more
|
||||
malleable. Salt accomplishes this via its ability to handle larger loads of
|
||||
information, and not just dozens, but hundreds or even thousands of individual
|
||||
servers, handle them quickly and through a simple and manageable interface.
|
||||
|
||||
%package api
|
||||
Summary: The api for Salt a parallel remote execution system
|
||||
Group: System/Management
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
Requires: %{name}-master = %{version}-%{release}
|
||||
%if 0%{?default_py3}
|
||||
Requires: python3-CherryPy >= 3.2.2
|
||||
%else
|
||||
Requires: python-CherryPy >= 3.2.2
|
||||
%endif
|
||||
|
||||
%description api
|
||||
salt-api is a modular interface on top of Salt that can provide a variety of entry points into a running Salt system.
|
||||
@ -397,7 +534,6 @@ Zsh command line completion support for %{name}.
|
||||
%setup -q -n salt-%{version}
|
||||
cp %{S:1} .
|
||||
cp %{S:5} ./.travis.yml
|
||||
cp %{S:6} ./zyppnotify
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
@ -406,10 +542,33 @@ cp %{S:6} ./zyppnotify
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
|
||||
%build
|
||||
%if 0%{?build_py2}
|
||||
%{__python} setup.py --with-salt-version=%{version} --salt-transport=both build
|
||||
cp ./build/lib/salt/_version.py ./salt
|
||||
mv build _build.python2
|
||||
%endif
|
||||
%if 0%{?build_py3}
|
||||
%{__python3} setup.py --with-salt-version=%{version} --salt-transport=both build
|
||||
cp ./build/lib/salt/_version.py ./salt
|
||||
mv build _build.python3
|
||||
%endif
|
||||
|
||||
%if %{with docs} && %{without builddocs}
|
||||
# extract docs from the tarball
|
||||
@ -425,7 +584,28 @@ cd doc && make html && rm _build/html/.buildinfo && rm _build/html/_images/proxy
|
||||
%endif
|
||||
|
||||
%install
|
||||
%if 0%{?build_py2}
|
||||
mv _build.python2 build
|
||||
%{__python} setup.py --salt-transport=both install --prefix=%{_prefix} --root=%{buildroot}
|
||||
mv build _build.python2
|
||||
%endif
|
||||
%if 0%{?build_py3}
|
||||
mv _build.python3 build
|
||||
%{__python3} setup.py --salt-transport=both install --prefix=%{_prefix} --root=%{buildroot}
|
||||
mv build _build.python3
|
||||
%endif
|
||||
|
||||
%if 0%{?default_py3}
|
||||
DEF_PYPATH=_build.python3/scripts-*/
|
||||
%else
|
||||
DEF_PYPATH=_build.python2/scripts-*/
|
||||
%endif
|
||||
|
||||
rm -f %{buildroot}%{_bindir}/*
|
||||
for script in $DEF_PYPATH/*; do
|
||||
install -m 0755 $script %{buildroot}%{_bindir}
|
||||
done
|
||||
|
||||
## create missing directories
|
||||
install -Dd -m 0750 %{buildroot}%{_sysconfdir}/salt/master.d
|
||||
install -Dd -m 0750 %{buildroot}%{_sysconfdir}/salt/minion.d
|
||||
@ -468,24 +648,24 @@ install -Dd -m 0750 %{buildroot}%{_sysconfdir}/salt/pki/minion
|
||||
## Install Zypper plugins only on SUSE machines
|
||||
%if 0%{?suse_version}
|
||||
install -Dd -m 0750 %{buildroot}%{_prefix}/lib/zypp/plugins/commit
|
||||
%{__install} zyppnotify %{buildroot}%{_prefix}/lib/zypp/plugins/commit/zyppnotify
|
||||
%{__install} scripts/suse/zypper/plugins/commit/zyppnotify %{buildroot}%{_prefix}/lib/zypp/plugins/commit/zyppnotify
|
||||
%endif
|
||||
|
||||
# Install Yum plugins only on RH machines
|
||||
%if 0%{?fedora} || 0%{?rhel}
|
||||
install -Dd %{buildroot}%{_prefix}/share/yum-plugins
|
||||
install -Dd %{buildroot}/etc/yum/pluginconf.d
|
||||
%{__install} scripts/yum/plugins/yumnotify.py %{buildroot}%{_prefix}/share/yum-plugins
|
||||
%{__install} scripts/yum/plugins/yumnotify.conf %{buildroot}/etc/yum/pluginconf.d
|
||||
%{__install} scripts/suse/yum/plugins/yumnotify.py %{buildroot}%{_prefix}/share/yum-plugins
|
||||
%{__install} scripts/suse/yum/plugins/yumnotify.conf %{buildroot}/etc/yum/pluginconf.d
|
||||
%endif
|
||||
|
||||
## install init and systemd scripts
|
||||
%if %{with systemd}
|
||||
install -Dpm 0644 pkg/salt-master.service %{buildroot}%{_unitdir}/salt-master.service
|
||||
install -Dpm 0644 pkg/suse/salt-master.service %{buildroot}%{_unitdir}/salt-master.service
|
||||
%if 0%{?suse_version}
|
||||
install -Dpm 0644 pkg/suse/salt-minion.service %{buildroot}%{_unitdir}/salt-minion.service
|
||||
%else
|
||||
install -Dpm 0644 pkg/salt-minion.service.rhel7 %{buildroot}%{_unitdir}/salt-minion.service
|
||||
install -Dpm 0644 pkg/suse/salt-minion.service.rhel7 %{buildroot}%{_unitdir}/salt-minion.service
|
||||
%endif
|
||||
install -Dpm 0644 pkg/salt-syndic.service %{buildroot}%{_unitdir}/salt-syndic.service
|
||||
install -Dpm 0644 pkg/suse/salt-api.service %{buildroot}%{_unitdir}/salt-api.service
|
||||
@ -510,7 +690,7 @@ ln -sf %{_initddir}/salt-api %{buildroot}%{_sbindir}/rcsalt-api
|
||||
|
||||
## Install sysV salt-minion watchdog for SLES11 and RHEL6
|
||||
%if 0%{?rhel} == 6 || 0%{?suse_version} == 1110
|
||||
install -Dpm 0755 scripts/watchdog/salt-daemon-watcher %{buildroot}%{_bindir}/salt-daemon-watcher
|
||||
install -Dpm 0755 scripts/suse/watchdog/salt-daemon-watcher %{buildroot}%{_bindir}/salt-daemon-watcher
|
||||
%endif
|
||||
|
||||
#
|
||||
@ -523,8 +703,12 @@ install -Dpm 0640 conf/cloud %{buildroot}%{_sysconfdir}/salt/cloud
|
||||
install -Dpm 0640 conf/cloud.profiles %{buildroot}%{_sysconfdir}/salt/cloud.profiles
|
||||
install -Dpm 0640 conf/cloud.providers %{buildroot}%{_sysconfdir}/salt/cloud.providers
|
||||
#
|
||||
## install logrotate file
|
||||
## install logrotate file (for RHEL6 we use without sudo)
|
||||
%if 0%{?rhel} > 6 || 0%{?suse_version}
|
||||
install -Dpm 0644 pkg/suse/salt-common.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/salt
|
||||
%else
|
||||
install -Dpm 0644 pkg/salt-common.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/salt
|
||||
%endif
|
||||
#
|
||||
## install SuSEfirewall2 rules
|
||||
install -Dpm 0644 pkg/suse/salt.SuSEfirewall2 %{buildroot}%{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/salt
|
||||
@ -544,12 +728,21 @@ install -Dpm 0644 pkg/fish-completions/* %{buildroot}%{fish_completions_dir}
|
||||
|
||||
%if 0%{?suse_version} > 1020
|
||||
%fdupes %{buildroot}%{_docdir}
|
||||
%if 0%{?build_py2}
|
||||
%fdupes %{buildroot}%{python_sitelib}
|
||||
%endif
|
||||
%if 0%{?build_py3}
|
||||
%fdupes %{buildroot}%{python3_sitelib}
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%check
|
||||
%if %{with test}
|
||||
python3 setup.py test --runtests-opts=-u
|
||||
%if 0%{?default_py3}
|
||||
%{__python3} setup.py test --runtests-opts=-u
|
||||
%else
|
||||
%{__python} setup.py test --runtests-opts=-u
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%pre
|
||||
@ -711,7 +904,7 @@ if [ $1 -eq 2 ] ; then
|
||||
true
|
||||
fi
|
||||
%if %{with systemd}
|
||||
if [ `rpm -q systemd --queryformat="%%{VERSION}"` -lt 228 ]; then
|
||||
if [ `rpm -q systemd --queryformat="%{VERSION}"` -lt 228 ]; then
|
||||
# On systemd < 228 the 'TasksTask' attribute is not available.
|
||||
# Removing TasksMax from salt-master.service on SLE12SP1 LTSS (bsc#985112)
|
||||
sed -i '/TasksMax=infinity/d' %{_unitdir}/salt-master.service
|
||||
@ -873,8 +1066,13 @@ fi
|
||||
%config(noreplace) %attr(0640, root, salt) %{_sysconfdir}/salt/cloud.profiles
|
||||
%config(noreplace) %attr(0640, root, salt) %{_sysconfdir}/salt/cloud.providers
|
||||
%dir %attr(0750, root, salt) %{_localstatedir}/cache/salt/cloud
|
||||
%if 0%{?default_py3}
|
||||
%{python3_sitelib}/salt/cloud/deploy/bootstrap-salt.sh
|
||||
%attr(755,root,root)%{python3_sitelib}/salt/cloud/deploy/bootstrap-salt.sh
|
||||
%else
|
||||
%{python_sitelib}/salt/cloud/deploy/bootstrap-salt.sh
|
||||
%attr(755,root,root)%{python_sitelib}/salt/cloud/deploy/bootstrap-salt.sh
|
||||
%endif
|
||||
%{_mandir}/man1/salt-cloud.1.*
|
||||
|
||||
%files ssh
|
||||
@ -985,9 +1183,6 @@ fi
|
||||
%{_mandir}/man1/salt-call.1.gz
|
||||
%{_mandir}/man1/spm.1.gz
|
||||
%config(noreplace) %{_sysconfdir}/logrotate.d/salt
|
||||
%{python3_sitelib}/*
|
||||
%exclude %{python3_sitelib}/salt/cloud/deploy/*.sh
|
||||
%attr(755,root,root)%{python3_sitelib}/salt/cloud/deploy/*.sh
|
||||
%doc LICENSE AUTHORS README.rst HACKING.rst README.SUSE
|
||||
#
|
||||
%dir %attr(0750, root, salt) %{_sysconfdir}/salt
|
||||
@ -1001,6 +1196,20 @@ fi
|
||||
%endif
|
||||
%{_mandir}/man1/salt.1.*
|
||||
|
||||
%if 0%{?build_py2}
|
||||
%files -n python2-salt
|
||||
%defattr(-,root,root,-)
|
||||
%{python_sitelib}/*
|
||||
%exclude %{python_sitelib}/salt/cloud/deploy/*.sh
|
||||
%endif
|
||||
|
||||
%if 0%{?build_py3}
|
||||
%files -n python3-salt
|
||||
%defattr(-,root,root,-)
|
||||
%{python3_sitelib}/*
|
||||
%exclude %{python3_sitelib}/salt/cloud/deploy/*.sh
|
||||
%endif
|
||||
|
||||
%if %{with docs}
|
||||
%files doc
|
||||
%defattr(-,root,root)
|
||||
@ -1030,3 +1239,5 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
|
||||
|
||||
|
25
set-shell-environment-variable-64.patch
Normal file
25
set-shell-environment-variable-64.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 7f207ed0aa45063e90db2452a311b91f34b1b7e2 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Renner <jrenner@suse.com>
|
||||
Date: Thu, 11 Jan 2018 15:55:25 +0100
|
||||
Subject: [PATCH] Set SHELL environment variable (#64)
|
||||
|
||||
---
|
||||
pkg/suse/salt-api.service | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/pkg/suse/salt-api.service b/pkg/suse/salt-api.service
|
||||
index 6634b74a7d..5c73bb9022 100644
|
||||
--- a/pkg/suse/salt-api.service
|
||||
+++ b/pkg/suse/salt-api.service
|
||||
@@ -6,6 +6,7 @@ After=network.target
|
||||
[Service]
|
||||
User=salt
|
||||
Type=simple
|
||||
+Environment=SHELL=/bin/bash
|
||||
LimitNOFILE=8192
|
||||
ExecStart=/usr/bin/salt-api
|
||||
TimeoutStopSec=3
|
||||
--
|
||||
2.13.6
|
||||
|
||||
|
50
split-only-strings-if-they-are-such.patch
Normal file
50
split-only-strings-if-they-are-such.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 358d18a0cc635b04503d5392ce337227c1f191af Mon Sep 17 00:00:00 2001
|
||||
From: Bo Maryniuk <bo@suse.de>
|
||||
Date: Thu, 14 Dec 2017 14:43:52 +0100
|
||||
Subject: [PATCH] Split only strings, if they are such
|
||||
|
||||
* Use unicode literals
|
||||
* Lintfix: PEP8
|
||||
|
||||
See: https://bugzilla.suse.com/show_bug.cgi?id=1072218
|
||||
https://github.com/saltstack/salt/pull/44991
|
||||
---
|
||||
salt/pillar/sql_base.py | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/salt/pillar/sql_base.py b/salt/pillar/sql_base.py
|
||||
index e7abceb134..a59c45331f 100644
|
||||
--- a/salt/pillar/sql_base.py
|
||||
+++ b/salt/pillar/sql_base.py
|
||||
@@ -168,7 +168,7 @@ More complete example for MySQL (to also show configuration)
|
||||
as_list: True
|
||||
with_lists: [1,3]
|
||||
'''
|
||||
-from __future__ import absolute_import
|
||||
+from __future__ import absolute_import, unicode_literals
|
||||
|
||||
# Please don't strip redundant parentheses from this file.
|
||||
# I have added some for clarity.
|
||||
@@ -275,7 +275,7 @@ class SqlBaseExtPillar(six.with_metaclass(abc.ABCMeta, object)):
|
||||
# May set 'as_list' from qb[1][2].
|
||||
else:
|
||||
defaults.update(qb[1])
|
||||
- if defaults['with_lists']:
|
||||
+ if defaults['with_lists'] and isinstance(defaults['with_lists'], six.string_types):
|
||||
defaults['with_lists'] = [
|
||||
int(i) for i in defaults['with_lists'].split(',')
|
||||
]
|
||||
@@ -437,8 +437,7 @@ class SqlBaseExtPillar(six.with_metaclass(abc.ABCMeta, object)):
|
||||
cursor.execute(details['query'], (minion_id,))
|
||||
|
||||
# Extract the field names the db has returned and process them
|
||||
- self.process_fields([row[0] for row in cursor.description],
|
||||
- details['depth'])
|
||||
+ self.process_fields([row[0] for row in cursor.description], details['depth'])
|
||||
self.enter_root(root)
|
||||
self.as_list = details['as_list']
|
||||
if details['with_lists']:
|
||||
--
|
||||
2.15.1
|
||||
|
||||
|
@ -4,10 +4,35 @@
|
||||
# Author: Bo Maryniuk <bo@suse.de>
|
||||
#
|
||||
|
||||
NO_SPHINX_PARAM="--without-sphinx"
|
||||
|
||||
function build_virtenv() {
|
||||
virtualenv --system-site-packages $1
|
||||
source $1/bin/activate
|
||||
pip install --upgrade pip
|
||||
if [ -z "$2" ]; then
|
||||
pip install -I Sphinx
|
||||
fi
|
||||
}
|
||||
|
||||
function check_env() {
|
||||
for cmd in "sphinx-build" "make" "quilt"; do
|
||||
if [[ -z "$1" || "$1" != "$NO_SPHINX_PARAM" ]] && [ ! -z "$(which sphinx-build 2>/dev/null)" ]; then
|
||||
cat <<EOF
|
||||
You've installed Spinx globally. But it might be outdated or
|
||||
clash with the version I am going to install into the temporary
|
||||
virtual environment from PIP.
|
||||
|
||||
Please consider to remove Sphinx from your system, perhaps?
|
||||
Or pass me "$NO_SPHINX_PARAM" param so I will try reusing yours
|
||||
and see what happens. :)
|
||||
|
||||
EOF
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
for cmd in "make" "quilt" "virtualenv" "pip"; do
|
||||
if [ -z "$(which $cmd 2>/dev/null)" ]; then
|
||||
echo "Error: '$cmd' is missing."
|
||||
echo "Error: '$cmd' is still missing. Install it, please."
|
||||
exit 1;
|
||||
fi
|
||||
done
|
||||
@ -26,7 +51,7 @@ function build_docs() {
|
||||
cd _build/html
|
||||
chmod -R -x+X *
|
||||
cd ..
|
||||
tar cvf - html | bzip2 > /tmp/html.tar.bz2
|
||||
tar cvf - html | bzip2 > $2/html.tar.bz2
|
||||
}
|
||||
|
||||
function write_changelog() {
|
||||
@ -46,19 +71,30 @@ EOF
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: $0 <your e-mail>"
|
||||
echo "Usage: $0 <your e-mail> [--without-sphinx]"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
check_env;
|
||||
check_env $2;
|
||||
|
||||
START=$(pwd)
|
||||
V_ENV="sphinx_doc_gen"
|
||||
V_TMP=$(mktemp -d)
|
||||
|
||||
for f in "salt.spec" "salt*tar.gz"; do
|
||||
cp -v $f $V_TMP
|
||||
done
|
||||
|
||||
cd $V_TMP;
|
||||
build_virtenv $V_ENV $2;
|
||||
|
||||
SRC_DIR="salt-$(cat salt.spec | grep ^Version: | cut -d: -f2 | sed -e 's/[[:blank:]]//g')";
|
||||
quilt_setup $SRC_DIR
|
||||
build_docs doc
|
||||
build_docs doc $V_TMP
|
||||
|
||||
cd $START
|
||||
rm -rf $SRC_DIR
|
||||
mv /tmp/html.tar.bz2 $START
|
||||
mv $V_TMP/html.tar.bz2 $START
|
||||
rm -rf $V_TMP
|
||||
|
||||
echo "Done"
|
||||
echo "---------------"
|
||||
|
@ -2,7 +2,7 @@ From 418bcf80ca263c5523e701801e97bae60fdf9b35 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
|
||||
<psuarezhernandez@suse.com>
|
||||
Date: Mon, 11 Sep 2017 19:57:28 +0200
|
||||
Subject: [PATCH 2/6] Use $HOME to get the user home directory instead using
|
||||
Subject: [PATCH] Use $HOME to get the user home directory instead using
|
||||
'~' char
|
||||
|
||||
---
|
||||
@ -24,5 +24,6 @@ index 480361fe23..00174c072f 100644
|
||||
|
||||
if [ ! -d "$(dirname ${_salt_cache_functions})" ]; then
|
||||
--
|
||||
2.14.2
|
||||
2.15.1
|
||||
|
||||
|
||||
|
3
v2017.7.2.tar.gz
Normal file
3
v2017.7.2.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b9f9dd9ddd129ddadadf963178383b50c32283aeb1c338d9c23cc01b11722db2
|
||||
size 11483585
|
59
zyppnotify
59
zyppnotify
@ -1,59 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (c) 2016 SUSE Linux LLC
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Author: Bo Maryniuk <bo@suse.de>
|
||||
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
|
||||
from zypp_plugin import Plugin
|
||||
|
||||
|
||||
class DriftDetector(Plugin):
|
||||
"""
|
||||
Return diff of the installed packages outside the Salt.
|
||||
"""
|
||||
def __init__(self):
|
||||
Plugin.__init__(self)
|
||||
self.ck_path = "/var/cache/salt/minion/rpmdb.cookie"
|
||||
self.rpm_path = "/var/lib/rpm/Packages"
|
||||
|
||||
def _get_mtime(self):
|
||||
'''
|
||||
Get the modified time of the RPM Database.
|
||||
Returns:
|
||||
Unix ticks
|
||||
'''
|
||||
return os.path.exists(self.rpm_path) and int(os.path.getmtime(self.rpm_path)) or 0
|
||||
|
||||
def _get_checksum(self):
|
||||
'''
|
||||
Get the checksum of the RPM Database.
|
||||
Returns:
|
||||
hexdigest
|
||||
'''
|
||||
digest = hashlib.md5()
|
||||
with open(self.rpm_path, "rb") as rpm_db_fh:
|
||||
while True:
|
||||
buff = rpm_db_fh.read(0x1000)
|
||||
if not buff:
|
||||
break
|
||||
digest.update(buff)
|
||||
|
||||
return digest.hexdigest()
|
||||
|
||||
def PLUGINEND(self, headers, body):
|
||||
"""
|
||||
Hook when plugin closes Zypper's transaction.
|
||||
"""
|
||||
if 'SALT_RUNNING' not in os.environ:
|
||||
with open(self.ck_path, 'w') as ck_fh:
|
||||
ck_fh.write('{chksum} {mtime}\n'.format(chksum=self._get_checksum(), mtime=self._get_mtime()))
|
||||
|
||||
self.ack()
|
||||
|
||||
|
||||
DriftDetector().main()
|
Loading…
Reference in New Issue
Block a user