Accepting request 473298 from home:bmaryniuk:branches:systemsmanagement:saltstack
Update to 2016.11.3 version, pkg deps fix OBS-URL: https://build.opensuse.org/request/show/473298 OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=87
This commit is contained in:
parent
02cd6e0087
commit
1033bb543d
@ -1,48 +0,0 @@
|
||||
From 409e1835e0f26295212d1d148d1e7b42cf7dc6b0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Calmer <mc@suse.de>
|
||||
Date: Thu, 19 Jan 2017 15:39:10 +0100
|
||||
Subject: [PATCH] add buildargs option to dockerng.build
|
||||
|
||||
---
|
||||
salt/modules/dockerng.py | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/salt/modules/dockerng.py b/salt/modules/dockerng.py
|
||||
index 6c31c18289..87000e3846 100644
|
||||
--- a/salt/modules/dockerng.py
|
||||
+++ b/salt/modules/dockerng.py
|
||||
@@ -3553,7 +3553,8 @@ def build(path=None,
|
||||
rm=True,
|
||||
api_response=False,
|
||||
fileobj=None,
|
||||
- dockerfile=None):
|
||||
+ dockerfile=None,
|
||||
+ buildargs=None):
|
||||
'''
|
||||
Builds a docker image from a Dockerfile or a URL
|
||||
|
||||
@@ -3587,6 +3588,10 @@ def build(path=None,
|
||||
|
||||
.. versionadded:: develop
|
||||
|
||||
+ buildargs
|
||||
+ A dictionary of build arguments provided to the docker build process.
|
||||
+
|
||||
+
|
||||
**RETURN DATA**
|
||||
|
||||
A dictionary containing one or more of the following keys:
|
||||
@@ -3633,7 +3638,8 @@ def build(path=None,
|
||||
fileobj=fileobj,
|
||||
rm=rm,
|
||||
nocache=not cache,
|
||||
- dockerfile=dockerfile)
|
||||
+ dockerfile=dockerfile,
|
||||
+ buildargs=buildargs)
|
||||
ret = {'Time_Elapsed': time.time() - time_started}
|
||||
_clear_context()
|
||||
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
@ -1,21 +1,86 @@
|
||||
From ec727bbd931c8536b4f3cb1bf3f599432c063b3e Mon Sep 17 00:00:00 2001
|
||||
From 95d547d3e6c98f927eaad77346b84b2ccef95627 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Calmer <mc@suse.de>
|
||||
Date: Thu, 9 Feb 2017 12:44:43 +0100
|
||||
Subject: [PATCH] support dryrun for dockerng.sls_build
|
||||
Date: Thu, 19 Jan 2017 15:39:10 +0100
|
||||
Subject: [PATCH] add options for dockerng
|
||||
|
||||
* add buildargs option to dockerng.build
|
||||
* docker buildargs require minimal dockerpy 1.6.0 and docker version 1.9.0
|
||||
* update version in the docs
|
||||
* support dryrun for dockerng.sls_build
|
||||
|
||||
provide the possibility to put extra modules into the thin
|
||||
|
||||
added unit test for dockerng.sls_build dryrun option
|
||||
---
|
||||
salt/modules/dockerng.py | 29 +++++++++++--
|
||||
salt/modules/dockerng.py | 51 ++++++++++++++++++-----
|
||||
tests/unit/modules/dockerng_test.py | 82 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 108 insertions(+), 3 deletions(-)
|
||||
2 files changed, 122 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/salt/modules/dockerng.py b/salt/modules/dockerng.py
|
||||
index cbf2a6b397..bd0a208cac 100644
|
||||
index 29af703ffa..c199fede1e 100644
|
||||
--- a/salt/modules/dockerng.py
|
||||
+++ b/salt/modules/dockerng.py
|
||||
@@ -5757,7 +5757,9 @@ def call(name, function, *args, **kwargs):
|
||||
@@ -28,13 +28,13 @@ to replace references to ``dockerng`` with ``docker``.
|
||||
Installation Prerequisites
|
||||
--------------------------
|
||||
|
||||
-This execution module requires at least version 1.4.0 of both docker-py_ and
|
||||
-Docker_. docker-py can easily be installed using :py:func:`pip.install
|
||||
-<salt.modules.pip.install>`:
|
||||
+This execution module requires at least version 1.6.0 of docker-py_ and
|
||||
+version 1.9.0 of Docker_. docker-py can easily be installed using
|
||||
+:py:func:`pip.install <salt.modules.pip.install>`:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
- salt myminion pip.install docker-py>=1.4.0
|
||||
+ salt myminion pip.install docker-py>=1.6.0
|
||||
|
||||
.. _docker-py: https://pypi.python.org/pypi/docker-py
|
||||
.. _Docker: https://www.docker.com/
|
||||
@@ -332,8 +332,8 @@ __func_alias__ = {
|
||||
}
|
||||
|
||||
# Minimum supported versions
|
||||
-MIN_DOCKER = (1, 6, 0)
|
||||
-MIN_DOCKER_PY = (1, 4, 0)
|
||||
+MIN_DOCKER = (1, 9, 0)
|
||||
+MIN_DOCKER_PY = (1, 6, 0)
|
||||
|
||||
VERSION_RE = r'([\d.]+)'
|
||||
|
||||
@@ -3557,7 +3557,8 @@ def build(path=None,
|
||||
rm=True,
|
||||
api_response=False,
|
||||
fileobj=None,
|
||||
- dockerfile=None):
|
||||
+ dockerfile=None,
|
||||
+ buildargs=None):
|
||||
'''
|
||||
Builds a docker image from a Dockerfile or a URL
|
||||
|
||||
@@ -3591,6 +3592,10 @@ def build(path=None,
|
||||
|
||||
.. versionadded:: develop
|
||||
|
||||
+ buildargs
|
||||
+ A dictionary of build arguments provided to the docker build process.
|
||||
+
|
||||
+
|
||||
**RETURN DATA**
|
||||
|
||||
A dictionary containing one or more of the following keys:
|
||||
@@ -3637,7 +3642,8 @@ def build(path=None,
|
||||
fileobj=fileobj,
|
||||
rm=rm,
|
||||
nocache=not cache,
|
||||
- dockerfile=dockerfile)
|
||||
+ dockerfile=dockerfile,
|
||||
+ buildargs=buildargs)
|
||||
ret = {'Time_Elapsed': time.time() - time_started}
|
||||
_clear_context()
|
||||
|
||||
@@ -5755,7 +5761,9 @@ def call(name, function, *args, **kwargs):
|
||||
raise CommandExecutionError('Missing function parameter')
|
||||
|
||||
# move salt into the container
|
||||
@ -26,7 +91,7 @@ index cbf2a6b397..bd0a208cac 100644
|
||||
with io.open(thin_path, 'rb') as file:
|
||||
_client_wrapper('put_archive', name, thin_dest_path, file)
|
||||
try:
|
||||
@@ -5867,7 +5869,7 @@ def sls(name, mods=None, saltenv='base', **kwargs):
|
||||
@@ -5865,7 +5873,7 @@ def sls(name, mods=None, saltenv='base', **kwargs):
|
||||
|
||||
|
||||
def sls_build(name, base='opensuse/python', mods=None, saltenv='base',
|
||||
@ -35,7 +100,7 @@ index cbf2a6b397..bd0a208cac 100644
|
||||
'''
|
||||
Build a docker image using the specified sls modules and base image.
|
||||
|
||||
@@ -5875,6 +5877,24 @@ def sls_build(name, base='opensuse/python', mods=None, saltenv='base',
|
||||
@@ -5873,6 +5881,24 @@ def sls_build(name, base='opensuse/python', mods=None, saltenv='base',
|
||||
can build a docker image inside myminion that results of applying those
|
||||
states by doing:
|
||||
|
||||
@ -60,7 +125,7 @@ index cbf2a6b397..bd0a208cac 100644
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
@@ -5907,9 +5927,12 @@ def sls_build(name, base='opensuse/python', mods=None, saltenv='base',
|
||||
@@ -5905,9 +5931,12 @@ def sls_build(name, base='opensuse/python', mods=None, saltenv='base',
|
||||
# Now execute the state into the container
|
||||
ret = __salt__['dockerng.sls'](id_, mods, saltenv, **kwargs)
|
||||
# fail if the state was not successful
|
@ -1,4 +1,4 @@
|
||||
From 949591bc0a4c0e768c08a2f61c040a1c4f0190ed Mon Sep 17 00:00:00 2001
|
||||
From c4c6610bf7314cc4c6ecf656bef341e2d1ca1587 Mon Sep 17 00:00:00 2001
|
||||
From: Matei Albu <malbu@suse.de>
|
||||
Date: Mon, 19 Dec 2016 16:54:52 +0100
|
||||
Subject: [PATCH] Add --ssh-option to salt-ssh
|
||||
@ -16,7 +16,7 @@ Fix salt-ssh err when -ssh-option is missing
|
||||
3 files changed, 35 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/salt/client/ssh/__init__.py b/salt/client/ssh/__init__.py
|
||||
index f0b7a282c0..9ed6be2b75 100644
|
||||
index 23ec948fe0..bbef9d8de1 100644
|
||||
--- a/salt/client/ssh/__init__.py
|
||||
+++ b/salt/client/ssh/__init__.py
|
||||
@@ -295,6 +295,9 @@ class SSH(object):
|
||||
@ -29,7 +29,7 @@ index f0b7a282c0..9ed6be2b75 100644
|
||||
}
|
||||
if self.opts.get('rand_thin_dir'):
|
||||
self.defaults['thin_dir'] = os.path.join(
|
||||
@@ -690,6 +693,7 @@ class Single(object):
|
||||
@@ -693,6 +696,7 @@ class Single(object):
|
||||
identities_only=False,
|
||||
sudo_user=None,
|
||||
remote_port_forwards=None,
|
||||
@ -37,7 +37,7 @@ index f0b7a282c0..9ed6be2b75 100644
|
||||
**kwargs):
|
||||
# Get mine setting and mine_functions if defined in kwargs (from roster)
|
||||
self.mine = mine
|
||||
@@ -746,7 +750,8 @@ class Single(object):
|
||||
@@ -749,7 +753,8 @@ class Single(object):
|
||||
'mods': self.mods,
|
||||
'identities_only': identities_only,
|
||||
'sudo_user': sudo_user,
|
||||
@ -48,7 +48,7 @@ index f0b7a282c0..9ed6be2b75 100644
|
||||
self.minion_opts = {
|
||||
'grains_cache': True,
|
||||
diff --git a/salt/client/ssh/shell.py b/salt/client/ssh/shell.py
|
||||
index 722ec07633..2884a52c1d 100644
|
||||
index f78cb623e1..613660fe34 100644
|
||||
--- a/salt/client/ssh/shell.py
|
||||
+++ b/salt/client/ssh/shell.py
|
||||
@@ -64,7 +64,8 @@ class Shell(object):
|
||||
@ -59,9 +59,9 @@ index 722ec07633..2884a52c1d 100644
|
||||
+ remote_port_forwards=None,
|
||||
+ ssh_options=None):
|
||||
self.opts = opts
|
||||
self.host = host
|
||||
self.user = user
|
||||
@@ -77,6 +78,7 @@ class Shell(object):
|
||||
# ssh <ipv6>, but scp [<ipv6]:/path
|
||||
self.host = host.strip('[]')
|
||||
@@ -78,6 +79,7 @@ class Shell(object):
|
||||
self.mods = mods
|
||||
self.identities_only = identities_only
|
||||
self.remote_port_forwards = remote_port_forwards
|
||||
@ -69,7 +69,7 @@ index 722ec07633..2884a52c1d 100644
|
||||
|
||||
def get_error(self, errstr):
|
||||
'''
|
||||
@@ -168,6 +170,12 @@ class Shell(object):
|
||||
@@ -169,6 +171,12 @@ class Shell(object):
|
||||
ret.append('-o {0} '.format(option))
|
||||
return ''.join(ret)
|
||||
|
||||
@ -82,7 +82,7 @@ index 722ec07633..2884a52c1d 100644
|
||||
def _copy_id_str_old(self):
|
||||
'''
|
||||
Return the string to execute ssh-copy-id
|
||||
@@ -175,11 +183,12 @@ class Shell(object):
|
||||
@@ -176,11 +184,12 @@ class Shell(object):
|
||||
if self.passwd:
|
||||
# Using single quotes prevents shell expansion and
|
||||
# passwords containing '$'
|
||||
@ -96,7 +96,7 @@ index 722ec07633..2884a52c1d 100644
|
||||
self.user,
|
||||
self.host)
|
||||
return None
|
||||
@@ -192,11 +201,12 @@ class Shell(object):
|
||||
@@ -193,11 +202,12 @@ class Shell(object):
|
||||
if self.passwd:
|
||||
# Using single quotes prevents shell expansion and
|
||||
# passwords containing '$'
|
||||
@ -110,7 +110,7 @@ index 722ec07633..2884a52c1d 100644
|
||||
self.user,
|
||||
self.host)
|
||||
return None
|
||||
@@ -228,6 +238,9 @@ class Shell(object):
|
||||
@@ -229,6 +239,9 @@ class Shell(object):
|
||||
if ssh != 'scp' and self.remote_port_forwards:
|
||||
command.append(' '.join(['-R {0}'.format(item)
|
||||
for item in self.remote_port_forwards.split(',')]))
|
||||
@ -121,10 +121,10 @@ index 722ec07633..2884a52c1d 100644
|
||||
|
||||
return ' '.join(command)
|
||||
diff --git a/salt/utils/parsers.py b/salt/utils/parsers.py
|
||||
index e8f037c3d6..d91c846168 100644
|
||||
index 6330ed6596..c38506f3c5 100644
|
||||
--- a/salt/utils/parsers.py
|
||||
+++ b/salt/utils/parsers.py
|
||||
@@ -2838,11 +2838,11 @@ class SaltSSHOptionParser(six.with_metaclass(OptionParserMeta,
|
||||
@@ -2828,11 +2828,11 @@ class SaltSSHOptionParser(six.with_metaclass(OptionParserMeta,
|
||||
help='Pass a JID to be used instead of generating one.'
|
||||
)
|
||||
|
||||
@ -140,7 +140,7 @@ index e8f037c3d6..d91c846168 100644
|
||||
'--remote-port-forwards',
|
||||
dest='ssh_remote_port_forwards',
|
||||
help='Setup remote port forwarding using the same syntax as with '
|
||||
@@ -2850,7 +2850,15 @@ class SaltSSHOptionParser(six.with_metaclass(OptionParserMeta,
|
||||
@@ -2840,7 +2840,15 @@ class SaltSSHOptionParser(six.with_metaclass(OptionParserMeta,
|
||||
'forwarding definitions will be translated into multiple '
|
||||
'-R parameters.'
|
||||
)
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 3f950292cf9a3b6d6697e65f986e8559bc396cf2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Calmer <mc@suse.de>
|
||||
Date: Wed, 1 Feb 2017 16:57:13 +0100
|
||||
Subject: [PATCH] docker buildargs require minimal dockerpy 1.6.0 and
|
||||
docker version 1.9.0
|
||||
|
||||
update version in the docs
|
||||
---
|
||||
salt/modules/dockerng.py | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/salt/modules/dockerng.py b/salt/modules/dockerng.py
|
||||
index 87000e3846..f29108f1ba 100644
|
||||
--- a/salt/modules/dockerng.py
|
||||
+++ b/salt/modules/dockerng.py
|
||||
@@ -28,13 +28,13 @@ to replace references to ``dockerng`` with ``docker``.
|
||||
Installation Prerequisites
|
||||
--------------------------
|
||||
|
||||
-This execution module requires at least version 1.4.0 of both docker-py_ and
|
||||
-Docker_. docker-py can easily be installed using :py:func:`pip.install
|
||||
-<salt.modules.pip.install>`:
|
||||
+This execution module requires at least version 1.6.0 of docker-py_ and
|
||||
+version 1.9.0 of Docker_. docker-py can easily be installed using
|
||||
+:py:func:`pip.install <salt.modules.pip.install>`:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
- salt myminion pip.install docker-py>=1.4.0
|
||||
+ salt myminion pip.install docker-py>=1.6.0
|
||||
|
||||
.. _docker-py: https://pypi.python.org/pypi/docker-py
|
||||
.. _Docker: https://www.docker.com/
|
||||
@@ -332,8 +332,8 @@ __func_alias__ = {
|
||||
}
|
||||
|
||||
# Minimum supported versions
|
||||
-MIN_DOCKER = (1, 6, 0)
|
||||
-MIN_DOCKER_PY = (1, 4, 0)
|
||||
+MIN_DOCKER = (1, 9, 0)
|
||||
+MIN_DOCKER_PY = (1, 6, 0)
|
||||
|
||||
VERSION_RE = r'([\d.]+)'
|
||||
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 64ddef78a040dde7e547518331dc9e8a98ceb42f Mon Sep 17 00:00:00 2001
|
||||
From: Bo Maryniuk <bo@suse.de>
|
||||
Date: Thu, 5 Jan 2017 19:09:17 +0100
|
||||
Subject: [PATCH] Fix a typo for master comments
|
||||
|
||||
* Disable custom rosters in API
|
||||
* Pick up a specified roster file from the configured locations
|
||||
* Explain what it is about and how to configure that
|
||||
* Add docstring
|
||||
* Add explanation comment
|
||||
* Lintfix
|
||||
---
|
||||
conf/master | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/conf/master b/conf/master
|
||||
index f58eb496bf..3cfdae0a47 100644
|
||||
--- a/conf/master
|
||||
+++ b/conf/master
|
||||
@@ -405,7 +405,7 @@ syndic_user: salt
|
||||
# Pass in an alternative location for the salt-ssh roster file
|
||||
#roster_file: /etc/salt/roster
|
||||
|
||||
-# Define a location for roster files so they can be chosen when using Salt API.
|
||||
+# Define a locations for roster files so they can be chosen when using Salt API.
|
||||
# An administrator can place roster files into these locations. Then when
|
||||
# calling Salt API, parameter 'roster_file' should contain a relative path to
|
||||
# these locations. That is, "roster_file=/foo/roster" will be resolved as
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
26
fix-case-in-os_family-for-suse.patch
Normal file
26
fix-case-in-os_family-for-suse.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 036be5f7300bbf6c5ef3967b5cc935fd678cd1e1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Calmer <mc@suse.de>
|
||||
Date: Thu, 23 Feb 2017 12:01:05 +0100
|
||||
Subject: [PATCH] fix case in os_family for Suse
|
||||
|
||||
---
|
||||
salt/modules/service.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/salt/modules/service.py b/salt/modules/service.py
|
||||
index bb7133ee99..49186e4c9d 100644
|
||||
--- a/salt/modules/service.py
|
||||
+++ b/salt/modules/service.py
|
||||
@@ -53,7 +53,7 @@ def __virtual__():
|
||||
if __grains__['kernel'] != 'Linux':
|
||||
return (False, 'Non Linux OSes are not supported')
|
||||
# SUSE >=12.0 uses systemd
|
||||
- if __grains__.get('os_family', '') == 'SUSE':
|
||||
+ if __grains__.get('os_family', '') == 'Suse':
|
||||
try:
|
||||
# osrelease might be in decimal format (e.g. "12.1"), or for
|
||||
# SLES might include service pack (e.g. "11 SP3"), so split on
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
From 7c459f38d43ef31ededce703fbfb432af1fdcee6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Calmer <mc@suse.de>
|
||||
Date: Sat, 4 Feb 2017 16:05:45 +0100
|
||||
Subject: [PATCH] fix error parsing
|
||||
|
||||
---
|
||||
salt/modules/dockerng.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/salt/modules/dockerng.py b/salt/modules/dockerng.py
|
||||
index f29108f1ba..cbf2a6b397 100644
|
||||
--- a/salt/modules/dockerng.py
|
||||
+++ b/salt/modules/dockerng.py
|
||||
@@ -1204,7 +1204,7 @@ def _error_detail(data, item):
|
||||
'''
|
||||
err = item['errorDetail']
|
||||
if 'code' in err:
|
||||
- msg = '{1}: {2}'.format(
|
||||
+ msg = '{0}: {1}'.format(
|
||||
item['errorDetail']['code'],
|
||||
item['errorDetail']['message'],
|
||||
)
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
@ -1,94 +0,0 @@
|
||||
From dadd20bd0db0289ac4ad9f322f03de686b24c5a7 Mon Sep 17 00:00:00 2001
|
||||
From: Bo Maryniuk <bo@suse.de>
|
||||
Date: Wed, 25 Jan 2017 15:42:08 +0100
|
||||
Subject: [PATCH] Fix leading dots on sanitized hostname
|
||||
|
||||
Add unit test
|
||||
|
||||
Fix typo
|
||||
---
|
||||
salt/utils/sanitizers.py | 2 +-
|
||||
tests/unit/utils/sanitizers_test.py | 57 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 58 insertions(+), 1 deletion(-)
|
||||
create mode 100644 tests/unit/utils/sanitizers_test.py
|
||||
|
||||
diff --git a/salt/utils/sanitizers.py b/salt/utils/sanitizers.py
|
||||
index d05d39955d..83f621151a 100644
|
||||
--- a/salt/utils/sanitizers.py
|
||||
+++ b/salt/utils/sanitizers.py
|
||||
@@ -56,7 +56,7 @@ class InputSanitizer(object):
|
||||
:param value:
|
||||
:return:
|
||||
'''
|
||||
- return re.sub(r'[^a-zA-Z0-9.-]', '', InputSanitizer.trim(value))
|
||||
+ return re.sub(r'[^a-zA-Z0-9.-]', '', InputSanitizer.trim(value)).strip('.')
|
||||
|
||||
id = hostname
|
||||
|
||||
diff --git a/tests/unit/utils/sanitizers_test.py b/tests/unit/utils/sanitizers_test.py
|
||||
new file mode 100644
|
||||
index 0000000000..e9c333149c
|
||||
--- /dev/null
|
||||
+++ b/tests/unit/utils/sanitizers_test.py
|
||||
@@ -0,0 +1,57 @@
|
||||
+# -*- coding: utf-8 -*-
|
||||
+
|
||||
+# Import python libs
|
||||
+from __future__ import absolute_import
|
||||
+from salt.ext.six import text_type as text
|
||||
+
|
||||
+# Import Salt Libs
|
||||
+from salt.utils.sanitizers import clean
|
||||
+
|
||||
+# Import Salt Testing Libs
|
||||
+from salttesting import TestCase, skipIf
|
||||
+from salttesting.mock import NO_MOCK, NO_MOCK_REASON
|
||||
+from salttesting.helpers import ensure_in_syspath
|
||||
+
|
||||
+ensure_in_syspath('../../')
|
||||
+
|
||||
+
|
||||
+@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
+class SanitizersTestCase(TestCase):
|
||||
+ '''
|
||||
+ TestCase for sanitizers
|
||||
+ '''
|
||||
+ def test_sanitized_trim(self):
|
||||
+ '''
|
||||
+ Test sanitized input for trimming
|
||||
+ '''
|
||||
+ value = u' sample '
|
||||
+ response = clean.trim(value)
|
||||
+ assert response == 'sample'
|
||||
+ assert type(response) == text
|
||||
+
|
||||
+ def test_sanitized_filename(self):
|
||||
+ '''
|
||||
+ Test sanitized input for filename
|
||||
+ '''
|
||||
+ value = '/absolute/path/to/the/file.txt'
|
||||
+ response = clean.filename(value)
|
||||
+ assert response == 'file.txt'
|
||||
+
|
||||
+ value = '../relative/path/to/the/file.txt'
|
||||
+ response = clean.filename(value)
|
||||
+ assert response == 'file.txt'
|
||||
+
|
||||
+ def test_sanitized_hostname(self):
|
||||
+ '''
|
||||
+ Test sanitized input for hostname (id)
|
||||
+ '''
|
||||
+ value = ' ../ ../some/dubious/hostname '
|
||||
+ response = clean.hostname(value)
|
||||
+ assert response == 'somedubioushostname'
|
||||
+
|
||||
+ test_sanitized_id = test_sanitized_hostname
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ from integration import run_tests
|
||||
+ run_tests(SanitizersTestCase, needs_daemon=False)
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
196
fix-regression-in-file.get_managed-add-unit-tests.patch
Normal file
196
fix-regression-in-file.get_managed-add-unit-tests.patch
Normal file
@ -0,0 +1,196 @@
|
||||
From 89fd1a83d282a10728077a08466627271a052733 Mon Sep 17 00:00:00 2001
|
||||
From: Erik Johnson <palehose@gmail.com>
|
||||
Date: Wed, 1 Mar 2017 10:19:33 -0600
|
||||
Subject: [PATCH] Fix regression in file.get_managed, add unit tests
|
||||
|
||||
This is no longer needed since we're invoking the state module directly
|
||||
and not via the state compiler.
|
||||
|
||||
* Fix regression in file.get_managed when skip_verify=True
|
||||
* Add integration tests for remote file sources
|
||||
* Remove next(iter()) extraction
|
||||
---
|
||||
salt/modules/file.py | 6 +--
|
||||
salt/states/archive.py | 11 ----
|
||||
tests/integration/states/file.py | 105 +++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 108 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/salt/modules/file.py b/salt/modules/file.py
|
||||
index 8f0c6914b6..381800bc1a 100644
|
||||
--- a/salt/modules/file.py
|
||||
+++ b/salt/modules/file.py
|
||||
@@ -3745,13 +3745,13 @@ def get_managed(
|
||||
if cached_dest and (source_hash or skip_verify):
|
||||
htype = source_sum.get('hash_type', 'sha256')
|
||||
cached_sum = get_hash(cached_dest, form=htype)
|
||||
- if cached_sum != source_sum['hsum']:
|
||||
- cache_refetch = True
|
||||
- elif skip_verify:
|
||||
+ if skip_verify:
|
||||
# prev: if skip_verify or cached_sum == source_sum['hsum']:
|
||||
# but `cached_sum == source_sum['hsum']` is elliptical as prev if
|
||||
sfn = cached_dest
|
||||
source_sum = {'hsum': cached_sum, 'hash_type': htype}
|
||||
+ elif cached_sum != source_sum['hsum']:
|
||||
+ cache_refetch = True
|
||||
|
||||
# If we didn't have the template or remote file, let's get it
|
||||
# Similarly when the file has been updated and the cache has to be refreshed
|
||||
diff --git a/salt/states/archive.py b/salt/states/archive.py
|
||||
index c5df213620..46146e971e 100644
|
||||
--- a/salt/states/archive.py
|
||||
+++ b/salt/states/archive.py
|
||||
@@ -897,17 +897,6 @@ def extracted(name,
|
||||
ret['comment'] = '\n'.join([str(x) for x in file_result])
|
||||
return ret
|
||||
|
||||
- # Get actual state result. The state.single return is a single-element
|
||||
- # dictionary with the state's unique ID at the top level, and its value
|
||||
- # being the state's return dictionary. next(iter(dict_name)) will give
|
||||
- # us the value of the first key, so
|
||||
- # file_result[next(iter(file_result))] will give us the results of the
|
||||
- # state.single we just ran.
|
||||
- try:
|
||||
- file_result = file_result[next(iter(file_result))]
|
||||
- except AttributeError:
|
||||
- pass
|
||||
-
|
||||
try:
|
||||
if not file_result['result']:
|
||||
log.debug('failed to download {0}'.format(source_match))
|
||||
diff --git a/tests/integration/states/file.py b/tests/integration/states/file.py
|
||||
index d63f318064..faa83d00e8 100644
|
||||
--- a/tests/integration/states/file.py
|
||||
+++ b/tests/integration/states/file.py
|
||||
@@ -9,15 +9,22 @@ from __future__ import absolute_import
|
||||
from distutils.version import LooseVersion
|
||||
import errno
|
||||
import glob
|
||||
+import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import shutil
|
||||
+import socket
|
||||
import stat
|
||||
import tempfile
|
||||
import textwrap
|
||||
+import threading
|
||||
+import tornado.ioloop
|
||||
+import tornado.web
|
||||
import filecmp
|
||||
|
||||
+log = logging.getLogger(__name__)
|
||||
+
|
||||
# Import 3rd-party libs
|
||||
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
|
||||
|
||||
@@ -2392,6 +2399,104 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
|
||||
if check_file:
|
||||
self.run_function('file.remove', [file])
|
||||
|
||||
+
|
||||
+PORT = 9999
|
||||
+FILE_SOURCE = 'http://localhost:{0}/grail/scene33'.format(PORT)
|
||||
+FILE_HASH = 'd2feb3beb323c79fc7a0f44f1408b4a3'
|
||||
+STATE_DIR = os.path.join(integration.FILES, 'file', 'base')
|
||||
+
|
||||
+
|
||||
+class RemoteFileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
|
||||
+ '''
|
||||
+ Uses a local tornado webserver to test http(s) file.managed states with and
|
||||
+ without skip_verify
|
||||
+ '''
|
||||
+ @classmethod
|
||||
+ def webserver(cls):
|
||||
+ '''
|
||||
+ method to start tornado static web app
|
||||
+ '''
|
||||
+ application = tornado.web.Application([
|
||||
+ (r'/(.*)', tornado.web.StaticFileHandler, {'path': STATE_DIR})
|
||||
+ ])
|
||||
+ application.listen(PORT)
|
||||
+ tornado.ioloop.IOLoop.instance().start()
|
||||
+
|
||||
+ @classmethod
|
||||
+ def setUpClass(cls):
|
||||
+ '''
|
||||
+ start tornado app on thread and wait until it is running
|
||||
+ '''
|
||||
+ cls.server_thread = threading.Thread(target=cls.webserver)
|
||||
+ cls.server_thread.daemon = True
|
||||
+ cls.server_thread.start()
|
||||
+ # check if tornado app is up
|
||||
+ port_closed = True
|
||||
+ while port_closed:
|
||||
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
+ result = sock.connect_ex(('127.0.0.1', PORT))
|
||||
+ if result == 0:
|
||||
+ port_closed = False
|
||||
+
|
||||
+ @classmethod
|
||||
+ def tearDownClass(cls):
|
||||
+ tornado.ioloop.IOLoop.instance().stop()
|
||||
+ cls.server_thread.join()
|
||||
+
|
||||
+ def setUp(self):
|
||||
+ fd_, self.name = tempfile.mkstemp(dir=integration.TMP)
|
||||
+ try:
|
||||
+ os.close(fd_)
|
||||
+ except OSError as exc:
|
||||
+ if exc.errno != errno.EBADF:
|
||||
+ raise exc
|
||||
+ # Remove the file that mkstemp just created so that the states can test
|
||||
+ # creating a new file instead of a diff from a zero-length file.
|
||||
+ self.tearDown()
|
||||
+
|
||||
+ def tearDown(self):
|
||||
+ try:
|
||||
+ os.remove(self.name)
|
||||
+ except OSError as exc:
|
||||
+ if exc.errno != errno.ENOENT:
|
||||
+ raise exc
|
||||
+
|
||||
+ def test_file_managed_http_source_no_hash(self):
|
||||
+ '''
|
||||
+ Test a remote file with no hash
|
||||
+ '''
|
||||
+ ret = self.run_state('file.managed',
|
||||
+ name=self.name,
|
||||
+ source=FILE_SOURCE,
|
||||
+ skip_verify=False)
|
||||
+ log.debug('ret = %s', ret)
|
||||
+ # This should fail because no hash was provided
|
||||
+ self.assertSaltFalseReturn(ret)
|
||||
+
|
||||
+ def test_file_managed_http_source(self):
|
||||
+ '''
|
||||
+ Test a remote file with no hash
|
||||
+ '''
|
||||
+ ret = self.run_state('file.managed',
|
||||
+ name=self.name,
|
||||
+ source=FILE_SOURCE,
|
||||
+ source_hash=FILE_HASH,
|
||||
+ skip_verify=False)
|
||||
+ log.debug('ret = %s', ret)
|
||||
+ self.assertSaltTrueReturn(ret)
|
||||
+
|
||||
+ def test_file_managed_http_source_skip_verify(self):
|
||||
+ '''
|
||||
+ Test a remote file using skip_verify
|
||||
+ '''
|
||||
+ ret = self.run_state('file.managed',
|
||||
+ name=self.name,
|
||||
+ source=FILE_SOURCE,
|
||||
+ skip_verify=True)
|
||||
+ log.debug('ret = %s', ret)
|
||||
+ self.assertSaltTrueReturn(ret)
|
||||
+
|
||||
+
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(FileTest)
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
From f45b229c9fea4be349484d8d041c735fa78500b5 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Kobzik <fkobzik@suse.de>
|
||||
Date: Thu, 12 Jan 2017 16:02:47 +0100
|
||||
Subject: [PATCH] Fix timezone handling for rpm installtime (bsc#1017078)
|
||||
|
||||
Previously datetime.fromtimestamp was used. If used without additional
|
||||
parameters, this method returns date in the local timezone.
|
||||
|
||||
Our code took the result of fromtimestamp, appended 'Z' and returned
|
||||
this string. This is wrong as 'Z' means UTC (the client code parses this
|
||||
value as UTC, but it's in fact local time).
|
||||
|
||||
Fixed by using utcfromtimestamp.
|
||||
---
|
||||
salt/modules/rpm.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/salt/modules/rpm.py b/salt/modules/rpm.py
|
||||
index 68268dea1d..9dace3cb6f 100644
|
||||
--- a/salt/modules/rpm.py
|
||||
+++ b/salt/modules/rpm.py
|
||||
@@ -575,7 +575,7 @@ def info(*packages, **attr):
|
||||
# Convert Unix ticks into ISO time format
|
||||
if key in ['build_date', 'install_date']:
|
||||
try:
|
||||
- pkg_data[key] = datetime.datetime.fromtimestamp(int(value)).isoformat() + "Z"
|
||||
+ pkg_data[key] = datetime.datetime.utcfromtimestamp(int(value)).isoformat() + "Z"
|
||||
except ValueError:
|
||||
log.warning('Could not convert "{0}" into Unix time'.format(value))
|
||||
continue
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
@ -1,170 +0,0 @@
|
||||
From 1c22c72afce15585070829054e3460a61947e256 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
|
||||
<psuarezhernandez@suse.com>
|
||||
Date: Mon, 23 Jan 2017 12:10:22 +0000
|
||||
Subject: [PATCH] Increasing timeouts for running integrations tests
|
||||
|
||||
---
|
||||
tests/integration/__init__.py | 16 ++++++++--------
|
||||
tests/integration/runners/state.py | 2 +-
|
||||
tests/integration/shell/call.py | 6 +++---
|
||||
tests/integration/shell/key.py | 2 +-
|
||||
tests/integration/shell/matcher.py | 2 +-
|
||||
tests/integration/shell/runner.py | 2 +-
|
||||
6 files changed, 15 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py
|
||||
index a37ad61d2e..104566363a 100644
|
||||
--- a/tests/integration/__init__.py
|
||||
+++ b/tests/integration/__init__.py
|
||||
@@ -801,7 +801,7 @@ class TestDaemon(object):
|
||||
)
|
||||
sys.stdout.flush()
|
||||
process.start()
|
||||
- process.wait_until_running(timeout=15)
|
||||
+ process.wait_until_running(timeout=60)
|
||||
sys.stdout.write(
|
||||
'\r{0}\r'.format(
|
||||
' ' * getattr(self.parser.options, 'output_columns', PNUM)
|
||||
@@ -1863,14 +1863,14 @@ class ShellCase(AdaptedConfigurationTestCaseMixIn, ShellTestCase, ScriptPathMixi
|
||||
except OSError:
|
||||
os.chdir(INTEGRATION_TEST_DIR)
|
||||
|
||||
- def run_salt(self, arg_str, with_retcode=False, catch_stderr=False, timeout=30): # pylint: disable=W0221
|
||||
+ def run_salt(self, arg_str, with_retcode=False, catch_stderr=False, timeout=60): # pylint: disable=W0221
|
||||
'''
|
||||
Execute salt
|
||||
'''
|
||||
arg_str = '-c {0} {1}'.format(self.get_config_dir(), arg_str)
|
||||
return self.run_script('salt', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=timeout)
|
||||
|
||||
- def run_ssh(self, arg_str, with_retcode=False, catch_stderr=False, timeout=25): # pylint: disable=W0221
|
||||
+ def run_ssh(self, arg_str, with_retcode=False, catch_stderr=False, timeout=60): # pylint: disable=W0221
|
||||
'''
|
||||
Execute salt-ssh
|
||||
'''
|
||||
@@ -1885,7 +1885,7 @@ class ShellCase(AdaptedConfigurationTestCaseMixIn, ShellTestCase, ScriptPathMixi
|
||||
arg_str,
|
||||
timeout=timeout,
|
||||
async_flag=' --async' if async else '')
|
||||
- return self.run_script('salt-run', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=30)
|
||||
+ return self.run_script('salt-run', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=60)
|
||||
|
||||
def run_run_plus(self, fun, *arg, **kwargs):
|
||||
'''
|
||||
@@ -1932,7 +1932,7 @@ class ShellCase(AdaptedConfigurationTestCaseMixIn, ShellTestCase, ScriptPathMixi
|
||||
arg_str,
|
||||
catch_stderr=catch_stderr,
|
||||
with_retcode=with_retcode,
|
||||
- timeout=30
|
||||
+ timeout=60
|
||||
)
|
||||
|
||||
def run_cp(self, arg_str, with_retcode=False, catch_stderr=False):
|
||||
@@ -1940,16 +1940,16 @@ class ShellCase(AdaptedConfigurationTestCaseMixIn, ShellTestCase, ScriptPathMixi
|
||||
Execute salt-cp
|
||||
'''
|
||||
arg_str = '--config-dir {0} {1}'.format(self.get_config_dir(), arg_str)
|
||||
- return self.run_script('salt-cp', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=30)
|
||||
+ return self.run_script('salt-cp', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=60)
|
||||
|
||||
def run_call(self, arg_str, with_retcode=False, catch_stderr=False):
|
||||
'''
|
||||
Execute salt-call.
|
||||
'''
|
||||
arg_str = '--config-dir {0} {1}'.format(self.get_config_dir(), arg_str)
|
||||
- return self.run_script('salt-call', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=30)
|
||||
+ return self.run_script('salt-call', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=60)
|
||||
|
||||
- def run_cloud(self, arg_str, catch_stderr=False, timeout=15):
|
||||
+ def run_cloud(self, arg_str, catch_stderr=False, timeout=30):
|
||||
'''
|
||||
Execute salt-cloud
|
||||
'''
|
||||
diff --git a/tests/integration/runners/state.py b/tests/integration/runners/state.py
|
||||
index 07cfe15fe0..3ca74e915b 100644
|
||||
--- a/tests/integration/runners/state.py
|
||||
+++ b/tests/integration/runners/state.py
|
||||
@@ -109,7 +109,7 @@ class OrchEventTest(integration.ShellCase):
|
||||
Tests for orchestration events
|
||||
'''
|
||||
def setUp(self):
|
||||
- self.timeout = 15
|
||||
+ self.timeout = 60
|
||||
self.master_d_dir = os.path.join(self.get_config_dir(), 'master.d')
|
||||
try:
|
||||
os.makedirs(self.master_d_dir)
|
||||
diff --git a/tests/integration/shell/call.py b/tests/integration/shell/call.py
|
||||
index 275878f7ca..e444743720 100644
|
||||
--- a/tests/integration/shell/call.py
|
||||
+++ b/tests/integration/shell/call.py
|
||||
@@ -272,7 +272,7 @@ class CallTest(integration.ShellCase, testprogram.TestProgramCase, integration.S
|
||||
'--config-dir {0} --local cmd.run "echo foo"'.format(
|
||||
config_dir
|
||||
),
|
||||
- timeout=15
|
||||
+ timeout=60
|
||||
)
|
||||
try:
|
||||
self.assertIn('local:', ret)
|
||||
@@ -295,7 +295,7 @@ class CallTest(integration.ShellCase, testprogram.TestProgramCase, integration.S
|
||||
'--config-dir {0} cmd.run "echo foo"'.format(
|
||||
config_dir
|
||||
),
|
||||
- timeout=15
|
||||
+ timeout=60
|
||||
)
|
||||
self.assertIn('local:', ret)
|
||||
finally:
|
||||
@@ -325,7 +325,7 @@ class CallTest(integration.ShellCase, testprogram.TestProgramCase, integration.S
|
||||
'--config-dir {0} cmd.run "echo foo"'.format(
|
||||
config_dir
|
||||
),
|
||||
- timeout=15,
|
||||
+ timeout=60,
|
||||
catch_stderr=True,
|
||||
with_retcode=True
|
||||
)
|
||||
diff --git a/tests/integration/shell/key.py b/tests/integration/shell/key.py
|
||||
index bf13fff9a3..aeba671829 100644
|
||||
--- a/tests/integration/shell/key.py
|
||||
+++ b/tests/integration/shell/key.py
|
||||
@@ -265,7 +265,7 @@ class KeyTest(integration.ShellCase, integration.ShellCaseCommonTestsMixIn):
|
||||
'--config-dir {0} -L'.format(
|
||||
config_dir
|
||||
),
|
||||
- timeout=15
|
||||
+ timeout=60
|
||||
)
|
||||
try:
|
||||
self.assertIn('minion', '\n'.join(ret))
|
||||
diff --git a/tests/integration/shell/matcher.py b/tests/integration/shell/matcher.py
|
||||
index e1623ae1b2..2bc8e61220 100644
|
||||
--- a/tests/integration/shell/matcher.py
|
||||
+++ b/tests/integration/shell/matcher.py
|
||||
@@ -353,7 +353,7 @@ class MatchTest(integration.ShellCase, integration.ShellCaseCommonTestsMixIn):
|
||||
'--config-dir {0} minion test.ping'.format(
|
||||
config_dir
|
||||
),
|
||||
- timeout=15,
|
||||
+ timeout=60,
|
||||
catch_stderr=True,
|
||||
with_retcode=True
|
||||
)
|
||||
diff --git a/tests/integration/shell/runner.py b/tests/integration/shell/runner.py
|
||||
index 6d65d537b5..cf7257b93d 100644
|
||||
--- a/tests/integration/shell/runner.py
|
||||
+++ b/tests/integration/shell/runner.py
|
||||
@@ -109,7 +109,7 @@ class RunTest(integration.ShellCase, testprogram.TestProgramCase, integration.Sh
|
||||
'--config-dir {0} -d'.format(
|
||||
config_dir
|
||||
),
|
||||
- timeout=15,
|
||||
+ timeout=60,
|
||||
catch_stderr=True,
|
||||
with_retcode=True
|
||||
)
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
From 48a8dd97be9ddef45f249d530b9c7d1a593e5ac0 Mon Sep 17 00:00:00 2001
|
||||
From: Bo Maryniuk <bo@suse.de>
|
||||
Date: Fri, 27 Jan 2017 14:31:50 +0100
|
||||
Subject: [PATCH] Prevent crash on unknown to the repo package
|
||||
|
||||
---
|
||||
salt/states/pkg.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/salt/states/pkg.py b/salt/states/pkg.py
|
||||
index d81f0c00c7..7c3b27b9ac 100644
|
||||
--- a/salt/states/pkg.py
|
||||
+++ b/salt/states/pkg.py
|
||||
@@ -1909,7 +1909,7 @@ def latest(
|
||||
for pkg in desired_pkgs:
|
||||
if not avail.get(pkg):
|
||||
# Package either a) is up-to-date, or b) does not exist
|
||||
- if not cur[pkg]:
|
||||
+ if not cur.get(pkg):
|
||||
# Package does not exist
|
||||
msg = 'No information found for \'{0}\'.'.format(pkg)
|
||||
log.error(msg)
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
From a74360a87e11bbcd65d253426c930769f83361e4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
|
||||
<psuarezhernandez@suse.com>
|
||||
Date: Tue, 14 Feb 2017 16:13:32 +0000
|
||||
Subject: [PATCH] Prevents 'OSError' exception in case path doesn't exist
|
||||
|
||||
---
|
||||
salt/returners/local_cache.py | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/salt/returners/local_cache.py b/salt/returners/local_cache.py
|
||||
index e2d2979241..d46cb1e70c 100644
|
||||
--- a/salt/returners/local_cache.py
|
||||
+++ b/salt/returners/local_cache.py
|
||||
@@ -60,6 +60,9 @@ def _walk_through(job_dir):
|
||||
for top in os.listdir(job_dir):
|
||||
t_path = os.path.join(job_dir, top)
|
||||
|
||||
+ if not os.path.exists(t_path):
|
||||
+ continue
|
||||
+
|
||||
for final in os.listdir(t_path):
|
||||
load_path = os.path.join(t_path, final, LOAD_P)
|
||||
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f5c3d3cf4293d5b80a93790c76dec61421991c9c54222abd7327b3437ad13a43
|
||||
size 9114042
|
3
salt-2016.11.3.tar.gz
Normal file
3
salt-2016.11.3.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9d5849f38a858288ebc6ef790ced86ae724e61b06e3ee27e6cecf3f6c1ecbc51
|
||||
size 9163351
|
31
salt.changes
31
salt.changes
@ -1,3 +1,34 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Mar 3 09:36:17 UTC 2017 - bmaryniuk@suse.com
|
||||
|
||||
- Update to 2016.11.3
|
||||
See https://docs.saltstack.com/en/develop/topics/releases/2016.11.3.html
|
||||
for full changelog
|
||||
|
||||
- Use correct package names for PyYAML and MarkupSafe (tbechtold@suse.com)
|
||||
|
||||
- Changed:
|
||||
* add-ssh-option-to-salt-ssh.patch
|
||||
|
||||
- Added:
|
||||
* add-options-for-dockerng.patch
|
||||
* fix-case-in-os_family-for-suse.patch
|
||||
* fix-regression-in-file.get_managed-add-unit-tests.patch
|
||||
* translate-variable-arguments-if-they-contain-hidden-.patch
|
||||
|
||||
- Removed:
|
||||
* add-buildargs-option-to-dockerng.build.patch
|
||||
* docker-buildargs-require-minimal-dockerpy-1.6.0-and-.patch
|
||||
* fix-a-typo-for-master-comments.patch
|
||||
* fix-error-parsing.patch
|
||||
* fix-leading-dots-on-sanitized-hostname.patch
|
||||
* fix-timezone-handling-for-rpm-installtime-bsc-101707.patch
|
||||
* increasing-timeouts-for-running-integrations-tests.patch
|
||||
* prevent-crash-on-unknown-to-the-repo-package.patch
|
||||
* prevents-oserror-exception-in-case-path-doesn-t-exis.patch
|
||||
* snapper-module-improvements.patch
|
||||
* support-dryrun-for-dockerng.sls_build.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 16 14:41:48 UTC 2017 - bmaryniuk@suse.com
|
||||
|
||||
|
62
salt.spec
62
salt.spec
@ -37,7 +37,7 @@
|
||||
%bcond_with builddocs
|
||||
|
||||
Name: salt
|
||||
Version: 2016.11.2
|
||||
Version: 2016.11.3
|
||||
Release: 0
|
||||
Summary: A parallel remote execution system
|
||||
License: Apache-2.0
|
||||
@ -51,22 +51,21 @@ Source3: html.tar.bz2
|
||||
Source4: update-documentation.sh
|
||||
Source5: travis.yml
|
||||
|
||||
# We do not upstream this patch because this is something that we have to fix on our side
|
||||
# PATCH-FIX-OPENSUSE use-forking-daemon.patch tserong@suse.com -- We don't have python-systemd, so notify can't work
|
||||
# We do not upstream this patch because this is something that we have to fix on our side
|
||||
Patch1: tserong-suse.com-we-don-t-have-python-systemd-so-not.patch
|
||||
# We do not upstream this patch because this is suse custom configuration
|
||||
# PATCH-FIX-OPENSUSE use-salt-user-for-master.patch -- Run salt master as dedicated salt user
|
||||
# We do not upstream this patch because this is suse custom configuration
|
||||
Patch2: run-salt-master-as-dedicated-salt-user.patch
|
||||
# (see: https://trello.com/c/wh96lCD4/1528-get-rid-of-0003-check-if-byte-strings-are-properly-encoded-in-utf-8-patch-in-the-salt-package)
|
||||
# We do not upstream this patch because it has been fixed upstream
|
||||
# PATCH-FIX-OPENSUSE https://github.com/saltstack/salt/pull/30424
|
||||
# We do not upstream this patch because it has been fixed upstream
|
||||
# (see: https://trello.com/c/wh96lCD4/1528-get-rid-of-0003-check-if-byte-strings-are-properly-encoded-in-utf-8-patch-in-the-salt-package)
|
||||
Patch3: check-if-byte-strings-are-properly-encoded-in-utf-8.patch
|
||||
# We do not upstream this patch because the issue is on our side
|
||||
# PATCH-FIX-OPENSUSE prevent rebuilds in OBS
|
||||
# We do not upstream this patch because the issue is on our side
|
||||
Patch4: do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch
|
||||
# We do not upstream this because this is for SUSE only (15.08.2016)
|
||||
# PATCH-FIX-OPENSUSE Generate events from the Salt minion,
|
||||
# if Zypper has been used outside the Salt infrastructure
|
||||
# We do not upstream this because this is for SUSE only (15.08.2016) if Zypper has been used outside the Salt infrastructure
|
||||
Patch5: add-zypp-notify-plugin.patch
|
||||
# PATCH-FIX_OPENSUSE
|
||||
Patch6: run-salt-api-as-user-salt-bsc-990029.patch
|
||||
@ -82,30 +81,16 @@ Patch10: avoid-failures-on-sles-12-sp2-because-of-new-systemd.patch
|
||||
Patch11: add-yum-plugin.patch
|
||||
# PATCH-FIX_OPENSUSE
|
||||
Patch12: add-ssh-option-to-salt-ssh.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/38639/commits
|
||||
Patch13: fix-a-typo-for-master-comments.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/38806
|
||||
Patch14: add-a-salt-minion-service-control-file.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/38824
|
||||
Patch15: add-buildargs-option-to-dockerng.build.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/38885
|
||||
Patch16: increasing-timeouts-for-running-integrations-tests.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/38957
|
||||
Patch17: fix-timezone-handling-for-rpm-installtime-bsc-101707.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/38940/commits
|
||||
Patch18: fix-leading-dots-on-sanitized-hostname.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/38991
|
||||
Patch19: prevent-crash-on-unknown-to-the-repo-package.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/39111
|
||||
Patch20: docker-buildargs-require-minimal-dockerpy-1.6.0-and-.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/39179
|
||||
Patch21: fix-error-parsing.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/39162
|
||||
Patch22: snapper-module-improvements.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/39278
|
||||
Patch23: support-dryrun-for-dockerng.sls_build.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/39400
|
||||
Patch24: prevents-oserror-exception-in-case-path-doesn-t-exis.patch
|
||||
Patch13: add-a-salt-minion-service-control-file.patch
|
||||
# PATCH-FIX-OPENSUSE
|
||||
Patch14: add-options-for-dockerng.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/39591
|
||||
Patch15: fix-case-in-os_family-for-suse.patch
|
||||
# PATCH-FIX_OPENSUSE
|
||||
Patch16: translate-variable-arguments-if-they-contain-hidden-.patch
|
||||
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/39762
|
||||
Patch17: fix-regression-in-file.get_managed-add-unit-tests.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
BuildRequires: logrotate
|
||||
@ -117,13 +102,13 @@ BuildRequires: python-jinja2
|
||||
%else
|
||||
BuildRequires: python-Jinja2
|
||||
%endif
|
||||
BuildRequires: python-MarkupSafe
|
||||
BuildRequires: python-PyYAML
|
||||
BuildRequires: python-futures >= 2.0
|
||||
BuildRequires: python-markupsafe
|
||||
BuildRequires: python-msgpack-python > 0.3
|
||||
BuildRequires: python-psutil
|
||||
BuildRequires: python-requests >= 1.0.0
|
||||
BuildRequires: python-tornado >= 4.2.1
|
||||
BuildRequires: python-yaml
|
||||
# requirements/opt.txt (not all)
|
||||
# BuildRequires: python-MySQL-python
|
||||
# BuildRequires: python-timelib
|
||||
@ -182,13 +167,13 @@ Requires: yum
|
||||
%else
|
||||
Requires: python-Jinja2
|
||||
%endif
|
||||
Requires: python-MarkupSafe
|
||||
Requires: python-PyYAML
|
||||
Requires: python-futures >= 2.0
|
||||
Requires: python-markupsafe
|
||||
Requires: python-msgpack-python > 0.3
|
||||
Requires: python-psutil
|
||||
Requires: python-requests >= 1.0.0
|
||||
Requires: python-tornado >= 4.2.1
|
||||
Requires: python-yaml
|
||||
%if 0%{?suse_version}
|
||||
# required for zypper.py
|
||||
Requires: rpm-python
|
||||
@ -497,13 +482,6 @@ cp %{S:5} ./.travis.yml
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
|
||||
%build
|
||||
%{__python} setup.py --salt-transport=both build
|
||||
|
@ -1,275 +0,0 @@
|
||||
From 678de7117211fc359c9aa7e29f6c2fecf0944b08 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
|
||||
<psuarezhernandez@suse.com>
|
||||
Date: Fri, 27 Jan 2017 17:07:25 +0000
|
||||
Subject: [PATCH] Snapper module improvements
|
||||
|
||||
* Snapper: Adding support for deleting snapshots
|
||||
* Snapper: Adding support for snapshot metadata modification
|
||||
* Snapper: Adding support for creating configurations
|
||||
* Adds 'snapper.delete_snapshots' unit tests
|
||||
* Adds 'snapper.modify_snapshots' unit tests
|
||||
* Adds 'snapper.create_config' unit tests
|
||||
* Removing extra spaces
|
||||
* pylint fixes
|
||||
---
|
||||
salt/modules/snapper.py | 159 +++++++++++++++++++++++++++++++++++--
|
||||
tests/unit/modules/snapper_test.py | 50 ++++++++++++
|
||||
2 files changed, 201 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/salt/modules/snapper.py b/salt/modules/snapper.py
|
||||
index 318ce9b99d..d5f1181743 100644
|
||||
--- a/salt/modules/snapper.py
|
||||
+++ b/salt/modules/snapper.py
|
||||
@@ -290,6 +290,60 @@ def get_config(name='root'):
|
||||
)
|
||||
|
||||
|
||||
+def create_config(name=None,
|
||||
+ subvolume=None,
|
||||
+ fstype=None,
|
||||
+ template=None,
|
||||
+ extra_opts=None):
|
||||
+ '''
|
||||
+ Creates a new Snapper configuration
|
||||
+
|
||||
+ name
|
||||
+ Name of the new Snapper configuration.
|
||||
+ subvolume
|
||||
+ Path to the related subvolume.
|
||||
+ fstype
|
||||
+ Filesystem type of the subvolume.
|
||||
+ template
|
||||
+ Configuration template to use. (Default: default)
|
||||
+ extra_opts
|
||||
+ Extra Snapper configuration opts dictionary. It will override the values provided
|
||||
+ by the given template (if any).
|
||||
+
|
||||
+ CLI example:
|
||||
+
|
||||
+ .. code-block:: bash
|
||||
+
|
||||
+ salt '*' snapper.create_config name=myconfig subvolume=/foo/bar/ fstype=btrfs
|
||||
+ salt '*' snapper.create_config name=myconfig subvolume=/foo/bar/ fstype=btrfs template="default"
|
||||
+ salt '*' snapper.create_config name=myconfig subvolume=/foo/bar/ fstype=btrfs extra_opts='{"NUMBER_CLEANUP": False}'
|
||||
+ '''
|
||||
+ def raise_arg_error(argname):
|
||||
+ raise CommandExecutionError(
|
||||
+ 'You must provide a "{0}" for the new configuration'.format(argname)
|
||||
+ )
|
||||
+
|
||||
+ if not name:
|
||||
+ raise_arg_error("name")
|
||||
+ if not subvolume:
|
||||
+ raise_arg_error("subvolume")
|
||||
+ if not fstype:
|
||||
+ raise_arg_error("fstype")
|
||||
+ if not template:
|
||||
+ template = ""
|
||||
+
|
||||
+ try:
|
||||
+ snapper.CreateConfig(name, subvolume, fstype, template)
|
||||
+ if extra_opts:
|
||||
+ set_config(name, **extra_opts)
|
||||
+ return get_config(name)
|
||||
+ except dbus.DBusException as exc:
|
||||
+ raise CommandExecutionError(
|
||||
+ 'Error encountered while creating the new configuration: {0}'
|
||||
+ .format(_dbus_exception_to_reason(exc, locals()))
|
||||
+ )
|
||||
+
|
||||
+
|
||||
def create_snapshot(config='root', snapshot_type='single', pre_number=None,
|
||||
description=None, cleanup_algorithm='number', userdata=None,
|
||||
**kwargs):
|
||||
@@ -309,14 +363,14 @@ def create_snapshot(config='root', snapshot_type='single', pre_number=None,
|
||||
cleanup_algorithm
|
||||
Set the cleanup algorithm for the snapshot.
|
||||
|
||||
- number
|
||||
- Deletes old snapshots when a certain number of snapshots
|
||||
- is reached.
|
||||
- timeline
|
||||
- Deletes old snapshots but keeps a number of hourly,
|
||||
- daily, weekly, monthly and yearly snapshots.
|
||||
- empty-pre-post
|
||||
- Deletes pre/post snapshot pairs with empty diffs.
|
||||
+ number
|
||||
+ Deletes old snapshots when a certain number of snapshots
|
||||
+ is reached.
|
||||
+ timeline
|
||||
+ Deletes old snapshots but keeps a number of hourly,
|
||||
+ daily, weekly, monthly and yearly snapshots.
|
||||
+ empty-pre-post
|
||||
+ Deletes pre/post snapshot pairs with empty diffs.
|
||||
userdata
|
||||
Set userdata for the snapshot (key-value pairs).
|
||||
|
||||
@@ -364,6 +418,95 @@ def create_snapshot(config='root', snapshot_type='single', pre_number=None,
|
||||
return new_nr
|
||||
|
||||
|
||||
+def delete_snapshot(snapshots_ids=None, config="root"):
|
||||
+ '''
|
||||
+ Deletes an snapshot
|
||||
+
|
||||
+ config
|
||||
+ Configuration name. (Default: root)
|
||||
+
|
||||
+ snapshots_ids
|
||||
+ List of the snapshots IDs to be deleted.
|
||||
+
|
||||
+ CLI example:
|
||||
+
|
||||
+ .. code-block:: bash
|
||||
+
|
||||
+ salt '*' snapper.delete_snapshot 54
|
||||
+ salt '*' snapper.delete_snapshot config=root 54
|
||||
+ salt '*' snapper.delete_snapshot config=root snapshots_ids=[54,55,56]
|
||||
+ '''
|
||||
+ if not snapshots_ids:
|
||||
+ raise CommandExecutionError('Error: No snapshot ID has been provided')
|
||||
+ try:
|
||||
+ current_snapshots_ids = [x['id'] for x in list_snapshots(config)]
|
||||
+ if not isinstance(snapshots_ids, list):
|
||||
+ snapshots_ids = [snapshots_ids]
|
||||
+ if not set(snapshots_ids).issubset(set(current_snapshots_ids)):
|
||||
+ raise CommandExecutionError(
|
||||
+ "Error: Snapshots '{0}' not found".format(", ".join(
|
||||
+ [str(x) for x in set(snapshots_ids).difference(
|
||||
+ set(current_snapshots_ids))]))
|
||||
+ )
|
||||
+ snapper.DeleteSnapshots(config, snapshots_ids)
|
||||
+ return {config: {"ids": snapshots_ids, "status": "deleted"}}
|
||||
+ except dbus.DBusException as exc:
|
||||
+ raise CommandExecutionError(_dbus_exception_to_reason(exc, locals()))
|
||||
+
|
||||
+
|
||||
+def modify_snapshot(snapshot_id=None,
|
||||
+ description=None,
|
||||
+ userdata=None,
|
||||
+ cleanup=None,
|
||||
+ config="root"):
|
||||
+ '''
|
||||
+ Modify attributes of an existing snapshot.
|
||||
+
|
||||
+ config
|
||||
+ Configuration name. (Default: root)
|
||||
+
|
||||
+ snapshot_id
|
||||
+ ID of the snapshot to be modified.
|
||||
+
|
||||
+ cleanup
|
||||
+ Change the cleanup method of the snapshot. (str)
|
||||
+
|
||||
+ description
|
||||
+ Change the description of the snapshot. (str)
|
||||
+
|
||||
+ userdata
|
||||
+ Change the userdata dictionary of the snapshot. (dict)
|
||||
+
|
||||
+ CLI example:
|
||||
+
|
||||
+ .. code-block:: bash
|
||||
+
|
||||
+ salt '*' snapper.modify_snapshot 54 description="my snapshot description"
|
||||
+ salt '*' snapper.modify_snapshot 54 description="my snapshot description"
|
||||
+ salt '*' snapper.modify_snapshot 54 userdata='{"foo": "bar"}'
|
||||
+ salt '*' snapper.modify_snapshot snapshot_id=54 cleanup="number"
|
||||
+ '''
|
||||
+ if not snapshot_id:
|
||||
+ raise CommandExecutionError('Error: No snapshot ID has been provided')
|
||||
+
|
||||
+ snapshot = get_snapshot(config=config, number=snapshot_id)
|
||||
+ try:
|
||||
+ # Updating only the explicitely provided attributes by the user
|
||||
+ updated_opts = {
|
||||
+ 'description': description if description is not None else snapshot['description'],
|
||||
+ 'cleanup': cleanup if cleanup is not None else snapshot['cleanup'],
|
||||
+ 'userdata': userdata if userdata is not None else snapshot['userdata'],
|
||||
+ }
|
||||
+ snapper.SetSnapshot(config,
|
||||
+ snapshot_id,
|
||||
+ updated_opts['description'],
|
||||
+ updated_opts['cleanup'],
|
||||
+ updated_opts['userdata'])
|
||||
+ return get_snapshot(config=config, number=snapshot_id)
|
||||
+ except dbus.DBusException as exc:
|
||||
+ raise CommandExecutionError(_dbus_exception_to_reason(exc, locals()))
|
||||
+
|
||||
+
|
||||
def _get_num_interval(config, num_pre, num_post):
|
||||
'''
|
||||
Returns numerical interval based on optionals num_pre, num_post values
|
||||
diff --git a/tests/unit/modules/snapper_test.py b/tests/unit/modules/snapper_test.py
|
||||
index ca985cfd05..a5d9b7686e 100644
|
||||
--- a/tests/unit/modules/snapper_test.py
|
||||
+++ b/tests/unit/modules/snapper_test.py
|
||||
@@ -202,6 +202,26 @@ class SnapperTestCase(TestCase):
|
||||
self.assertEqual(snapper.status_to_string(128), ["extended attributes changed"])
|
||||
self.assertEqual(snapper.status_to_string(256), ["ACL info changed"])
|
||||
|
||||
+ @patch('salt.modules.snapper.snapper.CreateConfig', MagicMock())
|
||||
+ @patch('salt.modules.snapper.snapper.GetConfig', MagicMock(return_value=DBUS_RET['ListConfigs'][0]))
|
||||
+ def test_create_config(self):
|
||||
+ opts = {
|
||||
+ 'name': 'testconfig',
|
||||
+ 'subvolume': '/foo/bar/',
|
||||
+ 'fstype': 'btrfs',
|
||||
+ 'template': 'mytemplate',
|
||||
+ 'extra_opts': {"NUMBER_CLEANUP": False},
|
||||
+ }
|
||||
+ with patch('salt.modules.snapper.set_config', MagicMock()) as set_config_mock:
|
||||
+ self.assertEqual(snapper.create_config(**opts), DBUS_RET['ListConfigs'][0])
|
||||
+ set_config_mock.assert_called_with("testconfig", **opts['extra_opts'])
|
||||
+
|
||||
+ with patch('salt.modules.snapper.set_config', MagicMock()) as set_config_mock:
|
||||
+ del opts['extra_opts']
|
||||
+ self.assertEqual(snapper.create_config(**opts), DBUS_RET['ListConfigs'][0])
|
||||
+ assert not set_config_mock.called
|
||||
+ self.assertRaises(CommandExecutionError, snapper.create_config)
|
||||
+
|
||||
@patch('salt.modules.snapper.snapper.CreateSingleSnapshot', MagicMock(return_value=1234))
|
||||
@patch('salt.modules.snapper.snapper.CreatePreSnapshot', MagicMock(return_value=1234))
|
||||
@patch('salt.modules.snapper.snapper.CreatePostSnapshot', MagicMock(return_value=1234))
|
||||
@@ -216,6 +236,36 @@ class SnapperTestCase(TestCase):
|
||||
}
|
||||
self.assertEqual(snapper.create_snapshot(**opts), 1234)
|
||||
|
||||
+ @patch('salt.modules.snapper.snapper.DeleteSnapshots', MagicMock())
|
||||
+ @patch('salt.modules.snapper.snapper.ListSnapshots', MagicMock(return_value=DBUS_RET['ListSnapshots']))
|
||||
+ def test_delete_snapshot_id_success(self):
|
||||
+ self.assertEqual(snapper.delete_snapshot(snapshots_ids=43), {"root": {"ids": [43], "status": "deleted"}})
|
||||
+ self.assertEqual(snapper.delete_snapshot(snapshots_ids=[42, 43]), {"root": {"ids": [42, 43], "status": "deleted"}})
|
||||
+
|
||||
+ @patch('salt.modules.snapper.snapper.DeleteSnapshots', MagicMock())
|
||||
+ @patch('salt.modules.snapper.snapper.ListSnapshots', MagicMock(return_value=DBUS_RET['ListSnapshots']))
|
||||
+ def test_delete_snapshot_id_fail(self):
|
||||
+ self.assertRaises(CommandExecutionError, snapper.delete_snapshot)
|
||||
+ self.assertRaises(CommandExecutionError, snapper.delete_snapshot, snapshots_ids=1)
|
||||
+ self.assertRaises(CommandExecutionError, snapper.delete_snapshot, snapshots_ids=[1, 2])
|
||||
+
|
||||
+ @patch('salt.modules.snapper.snapper.SetSnapshot', MagicMock())
|
||||
+ def test_modify_snapshot(self):
|
||||
+ _ret = {
|
||||
+ 'userdata': {'userdata2': 'uservalue2'},
|
||||
+ 'description': 'UPDATED DESCRIPTION', 'timestamp': 1457006571,
|
||||
+ 'cleanup': 'number', 'user': 'root', 'type': 'pre', 'id': 42
|
||||
+ }
|
||||
+ _opts = {
|
||||
+ 'config': 'root',
|
||||
+ 'snapshot_id': 42,
|
||||
+ 'cleanup': 'number',
|
||||
+ 'description': 'UPDATED DESCRIPTION',
|
||||
+ 'userdata': {'userdata2': 'uservalue2'},
|
||||
+ }
|
||||
+ with patch('salt.modules.snapper.get_snapshot', MagicMock(side_effect=[DBUS_RET['ListSnapshots'][0], _ret])):
|
||||
+ self.assertDictEqual(snapper.modify_snapshot(**_opts), _ret)
|
||||
+
|
||||
@patch('salt.modules.snapper._get_last_snapshot', MagicMock(return_value={'id': 42}))
|
||||
def test__get_num_interval(self):
|
||||
self.assertEqual(snapper._get_num_interval(config=None, num_pre=None, num_post=None), (42, 0)) # pylint: disable=protected-access
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
91
translate-variable-arguments-if-they-contain-hidden-.patch
Normal file
91
translate-variable-arguments-if-they-contain-hidden-.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From 7313bf5574a72557a6389b9a991316d0b2c6f848 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Calmer <mc@suse.de>
|
||||
Date: Wed, 1 Mar 2017 15:37:04 +0100
|
||||
Subject: [PATCH] translate variable arguments if they contain hidden
|
||||
keywords (bsc#1025896)
|
||||
|
||||
- includes a test
|
||||
---
|
||||
salt/states/module.py | 30 ++++++++++++++++++++++--------
|
||||
tests/unit/states/module_test.py | 14 ++++++++++++++
|
||||
2 files changed, 36 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/salt/states/module.py b/salt/states/module.py
|
||||
index 686546832f..adc6e12c9d 100644
|
||||
--- a/salt/states/module.py
|
||||
+++ b/salt/states/module.py
|
||||
@@ -218,16 +218,30 @@ def run(name, **kwargs):
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
- if aspec.varargs and aspec.varargs in kwargs:
|
||||
- varargs = kwargs.pop(aspec.varargs)
|
||||
+ if aspec.varargs:
|
||||
+ if aspec.varargs == 'name':
|
||||
+ rarg = 'm_name'
|
||||
+ elif aspec.varargs == 'fun':
|
||||
+ rarg = 'm_fun'
|
||||
+ elif aspec.varargs == 'names':
|
||||
+ rarg = 'm_names'
|
||||
+ elif aspec.varargs == 'state':
|
||||
+ rarg = 'm_state'
|
||||
+ elif aspec.varargs == 'saltenv':
|
||||
+ rarg = 'm_saltenv'
|
||||
+ else:
|
||||
+ rarg = aspec.varargs
|
||||
|
||||
- if not isinstance(varargs, list):
|
||||
- msg = "'{0}' must be a list."
|
||||
- ret['comment'] = msg.format(aspec.varargs)
|
||||
- ret['result'] = False
|
||||
- return ret
|
||||
+ if rarg in kwargs:
|
||||
+ varargs = kwargs.pop(rarg)
|
||||
+
|
||||
+ if not isinstance(varargs, list):
|
||||
+ msg = "'{0}' must be a list."
|
||||
+ ret['comment'] = msg.format(aspec.varargs)
|
||||
+ ret['result'] = False
|
||||
+ return ret
|
||||
|
||||
- args.extend(varargs)
|
||||
+ args.extend(varargs)
|
||||
|
||||
nkwargs = {}
|
||||
if aspec.keywords and aspec.keywords in kwargs:
|
||||
diff --git a/tests/unit/states/module_test.py b/tests/unit/states/module_test.py
|
||||
index 0c025e3861..20dda73938 100644
|
||||
--- a/tests/unit/states/module_test.py
|
||||
+++ b/tests/unit/states/module_test.py
|
||||
@@ -38,6 +38,10 @@ class ModuleStateTest(TestCase):
|
||||
varargs=None,
|
||||
keywords=None,
|
||||
defaults=False)
|
||||
+ bspec = ArgSpec(args=[],
|
||||
+ varargs='names',
|
||||
+ keywords='kwargs',
|
||||
+ defaults=None)
|
||||
|
||||
def test_module_run_module_not_available(self):
|
||||
'''
|
||||
@@ -69,6 +73,16 @@ class ModuleStateTest(TestCase):
|
||||
comment = 'The following arguments are missing: world hello'
|
||||
self.assertEqual(ret['comment'], comment)
|
||||
|
||||
+ @patch('salt.utils.args.get_function_argspec', MagicMock(return_value=bspec))
|
||||
+ def test_module_run_hidden_varargs(self):
|
||||
+ '''
|
||||
+ Tests the return of module.run state when hidden varargs are used with
|
||||
+ wrong type.
|
||||
+ '''
|
||||
+ ret = module.run(CMD, m_names = 'anyname')
|
||||
+ comment = "'names' must be a list."
|
||||
+ self.assertEqual(ret['comment'], comment)
|
||||
+
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
--
|
||||
2.11.0
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user