SHA256
1
0
forked from pool/salt

Accepting request 430691 from systemsmanagement:saltstack:testing

- splitting out the susemanager integration plugins into their own
  subpackages. ATM this only contains the zypp plugin to tell
  susemanager about manually installed packages.

- Unit and integration tests fixes for 2016.3.2
  Add:
  * 0018-Unit-tests-fixes-for-2016.3.2.patch
  * 0019-Fix-snapper_test-for-python26.patch
  * 0020-Integration-tests-fixes-for-2016.3.2.patch

- Prevent pkg.install failure for expired keys (bsc#996455)
  Add:
  * 0017-Check-for-single-quote-before-splitting-on-single-qu.patch

- Required D-Bus and generating machine ID where it is missing

- Fix sphinx crashes when documentation is being generated
  Add script for documentation update.
  Add:
  * 0016-Improve-Mock-to-be-flexible-and-able-to-mock-methods.patch
  * update-documentation.sh

- Fix pkg.installed refresh repo failure (bsc#993549)
  Fix salt.states.pkgrepo.management no change failure (bsc#990440)
  Add:
  * 0014-Add-ignore_repo_failure-option-to-suppress-zypper-s-.patch
  * 0015-Remove-zypper-s-raise-exception-if-mod_repo-has-no-a.patch

- Deprecate status.uptime one version later
  Add:

OBS-URL: https://build.opensuse.org/request/show/430691
OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=77
This commit is contained in:
Klaus Kämpf 2016-09-28 07:49:13 +00:00 committed by Git OBS Bridge
parent 519e8f9688
commit 14ef6d2b51
31 changed files with 3287 additions and 651 deletions

View File

@ -1,7 +1,7 @@
From f9dbfde1c3e7782d78f6b0b2b6b564f61749941f Mon Sep 17 00:00:00 2001
From 3f8257601cb1224221e10e712c0377254714f6fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= <kkaempf@suse.de>
Date: Wed, 20 Jan 2016 11:00:15 +0100
Subject: [PATCH 01/12] tserong@suse.com -- We don't have python-systemd, so
Subject: [PATCH 01/13] tserong@suse.com -- We don't have python-systemd, so
notify can't work
---
@ -9,7 +9,7 @@ Subject: [PATCH 01/12] tserong@suse.com -- We don't have python-systemd, so
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/pkg/salt-master.service b/pkg/salt-master.service
index 0eadf88..2b0f326 100644
index 0eadf88a3837..2b0f32623571 100644
--- a/pkg/salt-master.service
+++ b/pkg/salt-master.service
@@ -4,8 +4,7 @@ After=network.target
@ -23,5 +23,5 @@ index 0eadf88..2b0f326 100644
KillMode=process
--
2.1.4
2.8.3

View File

@ -1,7 +1,7 @@
From af193a109fcae502c4cdd47507aea9f67d809b4b Mon Sep 17 00:00:00 2001
From e86b0bf279c7faea457dfb8152fe9f5c829e42be 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 02/12] Run salt master as dedicated salt user
Subject: [PATCH 02/13] Run salt master as dedicated salt user
---
conf/master | 3 ++-
@ -9,7 +9,7 @@ Subject: [PATCH 02/12] Run salt master as dedicated salt user
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/conf/master b/conf/master
index aae46ef..064828a 100644
index 1bbeb50c51b4..54d5f8f3ca75 100644
--- a/conf/master
+++ b/conf/master
@@ -25,7 +25,8 @@
@ -23,7 +23,7 @@ index aae46ef..064828a 100644
# The port used by the communication interface. The ret (return) port is the
# interface used for the file server, authentication, job returns, etc.
diff --git a/pkg/salt-common.logrotate b/pkg/salt-common.logrotate
index 3cd0023..8d970c0 100644
index 3cd002308e83..8d970c0a64d0 100644
--- a/pkg/salt-common.logrotate
+++ b/pkg/salt-common.logrotate
@@ -1,4 +1,5 @@
@ -49,5 +49,5 @@ index 3cd0023..8d970c0 100644
missingok
rotate 7
--
2.1.4
2.8.3

View File

@ -1,4 +1,4 @@
From 6035aef0c80ae12a068bee7613c5b7f7f48aa9d3 Mon Sep 17 00:00:00 2001
From cad9f1a8fda2a4d8c666abcf74e03e7c6a8eb6be Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Mon, 18 Jan 2016 16:28:48 +0100
Subject: [PATCH 03/12] Check if byte strings are properly encoded in UTF-8
@ -9,10 +9,10 @@ Rename keywords arguments variable to a default name.
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index fecb671..27b00d5 100644
index 7dd73dd..92c604e 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -164,9 +164,9 @@ def info_installed(*names, **kwargs):
@@ -335,9 +335,9 @@ def info_installed(*names, **kwargs):
summary, description.
:param errors:
@ -25,7 +25,7 @@ index fecb671..27b00d5 100644
Valid attributes are:
ignore, report
@@ -179,7 +179,8 @@ def info_installed(*names, **kwargs):
@@ -350,7 +350,8 @@ def info_installed(*names, **kwargs):
salt '*' pkg.info_installed <package1> <package2> <package3> ...
salt '*' pkg.info_installed <package1> attr=version,vendor
salt '*' pkg.info_installed <package1> <package2> <package3> ... attr=version,vendor
@ -35,7 +35,7 @@ index fecb671..27b00d5 100644
'''
ret = dict()
for pkg_name, pkg_nfo in __salt__['lowpkg.info'](*names, **kwargs).items():
@@ -190,7 +191,7 @@ def info_installed(*names, **kwargs):
@@ -361,7 +362,7 @@ def info_installed(*names, **kwargs):
# Check, if string is encoded in a proper UTF-8
value_ = value.decode('UTF-8', 'ignore').encode('UTF-8', 'ignore')
if value != value_:
@ -45,5 +45,5 @@ index fecb671..27b00d5 100644
if key == 'source_rpm':
t_nfo['source'] = value
--
2.1.4
2.9.2

View File

@ -1,7 +1,7 @@
From a2ffa8e54f3cd8dba3c4b73cad086a6b93fb3a41 Mon Sep 17 00:00:00 2001
From a831380a6d7f323c9824d26d6f6e5966b10cbc6e Mon Sep 17 00:00:00 2001
From: Michael Calmer <mc@suse.de>
Date: Fri, 4 Mar 2016 09:51:22 +0100
Subject: [PATCH 04/12] do not generate a date in a comment to prevent rebuilds
Subject: [PATCH 04/13] do not generate a date in a comment to prevent rebuilds
(bsc#969407)
---
@ -9,10 +9,10 @@ Subject: [PATCH 04/12] do not generate a date in a comment to prevent rebuilds
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/setup.py b/setup.py
index 742eae5..d2dd8f7 100755
index c84c19824a6f..819ec2b875d1 100755
--- a/setup.py
+++ b/setup.py
@@ -605,8 +605,7 @@ class Clean(clean):
@@ -618,8 +618,7 @@ class Clean(clean):
INSTALL_VERSION_TEMPLATE = '''\
@ -23,5 +23,5 @@ index 742eae5..d2dd8f7 100755
from salt.version import SaltStackVersion
--
2.1.4
2.8.3

View File

@ -1,4 +1,4 @@
From d5fc00efc2f73018c4c6bf3bea03648dfd1340fc Mon Sep 17 00:00:00 2001
From 03732c6879c45596b0a9a0e6500957ec4f9d8415 Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Thu, 17 Mar 2016 12:30:23 +0100
Subject: [PATCH 05/12] Use SHA256 hash type by default
@ -10,10 +10,10 @@ Subject: [PATCH 05/12] Use SHA256 hash type by default
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/conf/master b/conf/master
index 064828a..5e75b15 100644
index 8bbe490..118f53b 100644
--- a/conf/master
+++ b/conf/master
@@ -474,7 +474,7 @@ syndic_user: salt
@@ -509,7 +509,7 @@ syndic_user: salt
#
# Prior to changing this value, the master should be stopped and all Salt
# caches should be cleared.
@ -23,10 +23,10 @@ index 064828a..5e75b15 100644
# The buffer size in the file server can be adjusted here:
#file_buffer_size: 1048576
diff --git a/conf/minion b/conf/minion
index b408942..32b0d0a 100644
index 3ba8ba0..8e4dbd0 100644
--- a/conf/minion
+++ b/conf/minion
@@ -451,7 +451,7 @@
@@ -542,7 +542,7 @@
#
# Warning: Prior to changing this value, the minion should be stopped and all
# Salt caches should be cleared.
@ -36,10 +36,10 @@ index b408942..32b0d0a 100644
# The Salt pillar is searched for locally if file_client is set to local. If
# this is the case, and pillar data is defined, then the pillar_roots need to
diff --git a/conf/proxy b/conf/proxy
index e6ca631..e697357 100644
index 7b835e2..ab500f9 100644
--- a/conf/proxy
+++ b/conf/proxy
@@ -427,7 +427,7 @@
@@ -435,7 +435,7 @@
#
# Warning: Prior to changing this value, the minion should be stopped and all
# Salt caches should be cleared.
@ -49,5 +49,5 @@ index e6ca631..e697357 100644
# The Salt pillar is searched for locally if file_client is set to local. If
# this is the case, and pillar data is defined, then the pillar_roots need to
--
2.1.4
2.9.2

View File

@ -1,7 +1,7 @@
From e2236cc77888d3c359c23dfb47a57e1e057864bb Mon Sep 17 00:00:00 2001
From 46476c37aa00d9cbbd0ac58e56b7e1c134d33b13 Mon Sep 17 00:00:00 2001
From: Christian McHugh <mchugh19@hotmail.com>
Date: Thu, 10 Mar 2016 13:25:01 -0600
Subject: [PATCH 6/7] Create salt-proxy instantiated service file
Subject: [PATCH 06/13] Create salt-proxy instantiated service file
Add a systemd service file for salt-proxy.
@ -15,7 +15,7 @@ Instantiate a new proxy service with proxyid=p8000:
diff --git a/pkg/salt-proxy@.service b/pkg/salt-proxy@.service
new file mode 100644
index 0000000..f97120a
index 000000000000..f97120a05589
--- /dev/null
+++ b/pkg/salt-proxy@.service
@@ -0,0 +1,12 @@
@ -32,5 +32,5 @@ index 0000000..f97120a
+[Install]
+WantedBy=multi-user.target
--
2.8.2
2.8.3

View File

@ -1,7 +1,7 @@
From df87ac3485ff8b5013e720435905afda6b53ada8 Mon Sep 17 00:00:00 2001
From 65a32350589712835294bb5e671c42ef1d331df8 Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Mon, 9 May 2016 10:33:44 +0200
Subject: [PATCH 7/7] Add SUSE Manager plugin
Subject: [PATCH 07/13] Add SUSE Manager plugin
* Add unit test to the libzypp drift detector plugin
---
@ -17,7 +17,7 @@ Subject: [PATCH 7/7] Add SUSE Manager plugin
diff --git a/scripts/zypper/plugins/commit/README.md b/scripts/zypper/plugins/commit/README.md
new file mode 100644
index 0000000..01c8917
index 000000000000..01c8917c8e0a
--- /dev/null
+++ b/scripts/zypper/plugins/commit/README.md
@@ -0,0 +1,3 @@
@ -26,7 +26,7 @@ index 0000000..01c8917
+Plugins here are required to interact with SUSE Manager in conjunction of SaltStack and Zypper.
diff --git a/scripts/zypper/plugins/commit/susemanager b/scripts/zypper/plugins/commit/susemanager
new file mode 100755
index 0000000..268298b
index 000000000000..268298b10811
--- /dev/null
+++ b/scripts/zypper/plugins/commit/susemanager
@@ -0,0 +1,59 @@
@ -91,7 +91,7 @@ index 0000000..268298b
+DriftDetector().main()
diff --git a/tests/unit/zypp_plugins_test.py b/tests/unit/zypp_plugins_test.py
new file mode 100644
index 0000000..6075288
index 000000000000..6075288aad39
--- /dev/null
+++ b/tests/unit/zypp_plugins_test.py
@@ -0,0 +1,51 @@
@ -148,7 +148,7 @@ index 0000000..6075288
+ run_tests(ZyppPluginsTestCase, needs_daemon=False)
diff --git a/tests/zypp_plugin.py b/tests/zypp_plugin.py
new file mode 100644
index 0000000..218f703
index 000000000000..218f70381146
--- /dev/null
+++ b/tests/zypp_plugin.py
@@ -0,0 +1,64 @@
@ -217,5 +217,5 @@ index 0000000..218f703
+ '''
+ self.closed = True
--
2.8.2
2.8.3

View File

@ -1,25 +0,0 @@
From 46713681bda8e45667691fbda6efe808c81574b1 Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Mon, 23 May 2016 17:29:15 +0200
Subject: [PATCH 8/8] Prevent several minion processes on the same machine
---
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 c476fab..28cf32c 100644
--- a/pkg/suse/salt-minion
+++ b/pkg/suse/salt-minion
@@ -55,7 +55,7 @@ RETVAL=0
start() {
echo -n $"Starting salt-minion daemon: "
if [ -f $SUSE_RELEASE ]; then
- startproc -f -p /var/run/$SERVICE.pid $SALTMINION -d $MINION_ARGS
+ startproc -p /var/run/$SERVICE.pid $SALTMINION -d $MINION_ARGS
rc_status -v
elif [ -e $DEBIAN_VERSION ]; then
if [ -f $LOCKFILE ]; then
--
2.8.3

View File

@ -0,0 +1,43 @@
From c80528b9aad5305b06a07cadf752a45392d4a147 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
<psuarezhernandez@suse.com>
Date: Tue, 24 May 2016 11:01:55 +0100
Subject: [PATCH 08/12] checksum validation when zypper pkg.download
check the signature of downloaded RPM files
bugfix: showing errors when a package download fails using zypper pkg.download
Renamed check_sig to checksum and some refactoring
simpler rpm.checksum function
---
salt/modules/zypper.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index 92c604e..547d72b 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -1596,14 +1596,17 @@ def download(*packages, **kwargs):
pkg_ret = {}
for dld_result in __zypper__.xml.call('download', *packages).getElementsByTagName("download-result"):
repo = dld_result.getElementsByTagName("repository")[0]
+ path = dld_result.getElementsByTagName("localfile")[0].getAttribute("path")
pkg_info = {
'repository-name': repo.getAttribute('name'),
'repository-alias': repo.getAttribute('alias'),
+ 'path': path,
}
key = _get_first_aggregate_text(
dld_result.getElementsByTagName('name')
)
- pkg_ret[key] = pkg_info
+ if __salt__['lowpkg.checksum'](pkg_info['path']):
+ pkg_ret[key] = pkg_info
if pkg_ret:
failed = [pkg for pkg in packages if pkg not in pkg_ret]
--
2.8.2

View File

@ -1,74 +0,0 @@
From d27af7dee61e83165bbd9adb9f0b6dc467907faa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
<psuarezhernandez@suse.com>
Date: Tue, 24 May 2016 11:01:55 +0100
Subject: [PATCH 09/11] checksum validation when zypper pkg.download
check the signature of downloaded RPM files
bugfix: showing errors when a package download fails using zypper pkg.download
Renamed check_sig to checksum and some refactoring
simpler rpm.checksum function
---
salt/modules/rpm.py | 26 ++++++++++++++++++++++++++
salt/modules/zypper.py | 6 +++++-
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/salt/modules/rpm.py b/salt/modules/rpm.py
index 1469368..4991f24 100644
--- a/salt/modules/rpm.py
+++ b/salt/modules/rpm.py
@@ -602,3 +602,29 @@ def version_cmp(ver1, ver2):
log.warning("Failed to compare version '{0}' to '{1}' using RPM: {2}".format(ver1, ver2, exc))
return salt.utils.version_cmp(ver1, ver2)
+
+
+def checksum(*paths):
+ '''
+ Return if the signature of a RPM file is valid.
+
+ CLI Example:
+
+ .. code-block:: bash
+
+ salt '*' lowpkg.checksum /path/to/package1.rpm
+ salt '*' lowpkg.checksum /path/to/package1.rpm /path/to/package2.rpm
+ '''
+ ret = dict()
+
+ if not paths:
+ raise CommandExecutionError("No package files has been specified.")
+
+ for package_file in paths:
+ ret[package_file] = (bool(__salt__['file.file_exists'](package_file)) and
+ not __salt__['cmd.retcode'](["rpm", "-K", "--quiet", package_file],
+ ignore_retcode=True,
+ output_loglevel='trace',
+ python_shell=False))
+
+ return ret
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index f9538e5..39b071b 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -1534,9 +1534,13 @@ def download(*packages, **kwargs):
'repository-alias': repo.getAttribute("alias"),
'path': dld_result.getElementsByTagName("localfile")[0].getAttribute("path"),
}
- pkg_ret[_get_first_aggregate_text(dld_result.getElementsByTagName("name"))] = pkg_info
+ if __salt__['lowpkg.checksum'](pkg_info['path']):
+ pkg_ret[_get_first_aggregate_text(dld_result.getElementsByTagName("name"))] = pkg_info
if pkg_ret:
+ failed = [pkg for pkg in packages if pkg not in pkg_ret]
+ if failed:
+ pkg_ret['_error'] = ('The following package(s) failed to download: {0}'.format(', '.join(failed)))
return pkg_ret
raise CommandExecutionError("Unable to download packages: {0}.".format(', '.join(packages)))
--
2.8.2

View File

@ -0,0 +1,26 @@
From f186137c0eb7a14697037bf46ec6a12287b9e0c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
<psuarezhernandez@suse.com>
Date: Wed, 25 May 2016 17:08:16 +0100
Subject: [PATCH 09/12] unit tests for rpm.checksum() and zypper.download()
lint issue fixed
---
tests/unit/modules/zypper_test.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/unit/modules/zypper_test.py b/tests/unit/modules/zypper_test.py
index 308bf94..2f2b323 100644
--- a/tests/unit/modules/zypper_test.py
+++ b/tests/unit/modules/zypper_test.py
@@ -387,6 +387,7 @@ class ZypperTestCase(TestCase):
test_out = {
'nmap': {
+ 'path': u'/var/cache/zypp/packages/SLE-12-x86_64-Pool/x86_64/nmap-6.46-1.72.x86_64.rpm',
'repository-alias': u'SLE-12-x86_64-Pool',
'repository-name': u'SLE-12-x86_64-Pool'
}
--
2.9.2

File diff suppressed because it is too large Load Diff

View File

@ -1,105 +0,0 @@
From 2742ee76ccc50cd4f84e44861ef82ec5f3b5234a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
<psuarezhernandez@suse.com>
Date: Wed, 25 May 2016 17:08:16 +0100
Subject: [PATCH 10/11] unit tests for rpm.checksum() and zypper.download()
lint issue fixed
---
tests/unit/modules/rpm_test.py | 16 ++++++++++++++++
tests/unit/modules/zypp/zypper-download.xml | 19 +++++++++++++++++++
tests/unit/modules/zypper_test.py | 25 +++++++++++++++++++++++++
3 files changed, 60 insertions(+)
create mode 100644 tests/unit/modules/zypp/zypper-download.xml
diff --git a/tests/unit/modules/rpm_test.py b/tests/unit/modules/rpm_test.py
index f180736..4042137 100644
--- a/tests/unit/modules/rpm_test.py
+++ b/tests/unit/modules/rpm_test.py
@@ -95,6 +95,22 @@ class RpmTestCase(TestCase):
self.assertDictEqual(rpm.owner('/usr/bin/python', '/usr/bin/vim'),
ret)
+ # 'checksum' function tests: 1
+
+ def test_checksum(self):
+ '''
+ Test if checksum validate as expected
+ '''
+ ret = {
+ "file1.rpm": True,
+ "file2.rpm": False,
+ "file3.rpm": False,
+ }
+
+ mock = MagicMock(side_effect=[True, 0, True, 1, False, 0])
+ with patch.dict(rpm.__salt__, {'file.file_exists': mock, 'cmd.retcode': mock}):
+ self.assertDictEqual(rpm.checksum("file1.rpm", "file2.rpm", "file3.rpm"), ret)
+
@patch('salt.modules.rpm.HAS_RPM', True)
def test_version_cmp_rpm(self):
'''
diff --git a/tests/unit/modules/zypp/zypper-download.xml b/tests/unit/modules/zypp/zypper-download.xml
new file mode 100644
index 0000000..eeea0a5
--- /dev/null
+++ b/tests/unit/modules/zypp/zypper-download.xml
@@ -0,0 +1,19 @@
+<?xml version='1.0'?>
+<stream>
+ <message type="info">Loading repository data...</message>
+ <message type="info">Reading installed packages...</message>
+ <message type="warning">Argument resolves to no package: foo</message>
+ <progress id="" name="(1/1) /var/cache/zypp/packages/SLE-12-x86_64-Pool/x86_64/nmap-6.46-1.72.x86_64.rpm"/>
+ <download-result>
+ <solvable>
+ <kind>package</kind>
+ <name>nmap</name>
+ <edition epoch="0" version="6.46" release="1.72"/>
+ <arch>x86_64</arch>
+ <repository name="SLE-12-x86_64-Pool" alias="SLE-12-x86_64-Pool"/>
+ </solvable>
+ <localfile path="/var/cache/zypp/packages/SLE-12-x86_64-Pool/x86_64/nmap-6.46-1.72.x86_64.rpm"/>
+ </download-result>
+ <progress id="" name="(1/1) /var/cache/zypp/packages/SLE-12-x86_64-Pool/x86_64/nmap-6.46-1.72.x86_64.rpm" done="0"/>
+ <message type="info">download: Done.</message>
+</stream>
diff --git a/tests/unit/modules/zypper_test.py b/tests/unit/modules/zypper_test.py
index 4e735cd..9ec2b83 100644
--- a/tests/unit/modules/zypper_test.py
+++ b/tests/unit/modules/zypper_test.py
@@ -354,6 +354,31 @@ class ZypperTestCase(TestCase):
self.assertTrue(pkgs.get(pkg_name))
self.assertEqual(pkgs[pkg_name], pkg_version)
+ def test_download(self):
+ '''
+ Test package download
+ :return:
+ '''
+ download_out = {
+ 'stdout': get_test_data('zypper-download.xml'),
+ 'stderr': None,
+ 'retcode': 0
+ }
+
+ test_out = {
+ 'nmap': {
+ 'path': u'/var/cache/zypp/packages/SLE-12-x86_64-Pool/x86_64/nmap-6.46-1.72.x86_64.rpm',
+ 'repository-alias': u'SLE-12-x86_64-Pool',
+ 'repository-name': u'SLE-12-x86_64-Pool'
+ }
+ }
+
+ with patch.dict(zypper.__salt__, {'cmd.run_all': MagicMock(return_value=download_out)}):
+ with patch.dict(zypper.__salt__, {'lowpkg.checksum': MagicMock(return_value=True)}):
+ self.assertEqual(zypper.download("nmap"), test_out)
+ test_out['_error'] = "The following package(s) failed to download: foo"
+ self.assertEqual(zypper.download("nmap", "foo"), test_out)
+
def test_remove_purge(self):
'''
Test package removal
--
2.8.2

View File

@ -0,0 +1,29 @@
From e3969a80bdf2d0af0c87463af859d8daf314f018 Mon Sep 17 00:00:00 2001
From: Michael Calmer <mc@suse.de>
Date: Tue, 21 Jun 2016 13:12:48 +0200
Subject: [PATCH 11/12] fix salt --summary to count not responding minions
correctly (bsc#972311)
In case a minion is not responding a dict is returned instead of a string.
---
salt/cli/salt.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/salt/cli/salt.py b/salt/cli/salt.py
index baeaf23..ec18f2e 100644
--- a/salt/cli/salt.py
+++ b/salt/cli/salt.py
@@ -264,7 +264,9 @@ class SaltCMD(parsers.SaltCMDOptionParser):
not_connected_minions = []
failed_minions = []
for each_minion in ret:
- minion_ret = ret[each_minion].get('ret')
+ minion_ret = ret[each_minion]
+ if (isinstance(minion_ret, dict) and 'ret' in minion_ret):
+ minion_ret = ret[each_minion].get('ret')
if (
isinstance(minion_ret, string_types)
and minion_ret.startswith("Minion did not return")
--
2.9.2

View File

@ -1,53 +0,0 @@
From e0f15c5292869549b5c80997ccb3282961be8e49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
<psuarezhernandez@suse.com>
Date: Tue, 24 May 2016 09:21:43 +0100
Subject: [PATCH 11/11] jobs.exit_success allow to check if a job has executed
and exit successfully
jobs.exit_success() now works parsing the results of jobs.lookup_id()
---
salt/runners/jobs.py | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/salt/runners/jobs.py b/salt/runners/jobs.py
index 57d0324..e2b8737 100644
--- a/salt/runners/jobs.py
+++ b/salt/runners/jobs.py
@@ -488,6 +488,33 @@ def print_job(jid, ext_source=None, outputter=None):
return ret
+def exit_success(jid, ext_source=None):
+ '''
+ Check if a job has been executed and exit successfully
+
+ jid
+ The jid to look up.
+ ext_source
+ The external job cache to use. Default: `None`.
+
+ CLI Example:
+ .. code-block:: bash
+ salt-run jobs.exit_success 20160520145827701627
+ '''
+ ret = dict()
+
+ data = lookup_jid(
+ jid,
+ ext_source=ext_source
+ )
+
+ for minion in data:
+ if "retcode" in data[minion]:
+ ret[minion] = True if not data[minion]['retcode'] else False
+
+ return ret
+
+
def last_run(ext_source=None,
outputter=None,
metadata=None,
--
2.8.2

View File

@ -1,325 +0,0 @@
From b0e1ba5158cc4b54102bac200ae343935eeb2db5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mihai=20Dinc=C4=83?= <dincamihai@users.noreply.github.com>
Date: Mon, 23 May 2016 23:15:29 +0200
Subject: [PATCH 12/12] Fix pkgrepo.managed gpgkey argument (bsc#979448)
* Call zypper refresh after adding/modifying a repository
* Calling `zypper --gpg-auto-import-keys refresh` is required after
adding/modifying a repository because `--gpg-auto-import-keys` doesn't
do anything when called with `zypper ar` or `zypper mr`.
Without calling `zypper --gpg-auto-import-keys refresh` here, calling
`zypper ref` after adding/removing would still ask for
accepting/rejecting the gpg key.
* Update test method names to pass pylint
* Reduce dicts and lists to one line where possible
* Reverse if conditions and rename variable
* Assert only gpgautoimport: True works
* Improve zypper_patcher_config looks
* DRY test
---
salt/modules/zypper.py | 24 +++--
tests/unit/modules/zypper_test.py | 213 ++++++++++++++++++++++++++++++++++++++
2 files changed, 229 insertions(+), 8 deletions(-)
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index 39b071b..2c72448 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -767,6 +767,8 @@ def mod_repo(repo, **kwargs):
# Modify added or existing repo according to the options
cmd_opt = []
+ global_cmd_opt = []
+ call_refresh = False
if 'enabled' in kwargs:
cmd_opt.append(kwargs['enabled'] and '--enable' or '--disable')
@@ -780,21 +782,27 @@ def mod_repo(repo, **kwargs):
if 'gpgcheck' in kwargs:
cmd_opt.append(kwargs['gpgcheck'] and '--gpgcheck' or '--no-gpgcheck')
- if kwargs.get('gpgautoimport') is True:
- cmd_opt.append('--gpg-auto-import-keys')
-
if 'priority' in kwargs:
cmd_opt.append("--priority={0}".format(kwargs.get('priority', DEFAULT_PRIORITY)))
if 'humanname' in kwargs:
cmd_opt.append("--name='{0}'".format(kwargs.get('humanname')))
- if cmd_opt:
- cmd_opt.append(repo)
- __zypper__.refreshable.xml.call('mr', *cmd_opt)
+ if kwargs.get('gpgautoimport') is True:
+ global_cmd_opt.append('--gpg-auto-import-keys')
+ call_refresh = True
- # If repo nor added neither modified, error should be thrown
- if not added and not cmd_opt:
+ if cmd_opt:
+ cmd_opt = global_cmd_opt + ['mr'] + cmd_opt + [repo]
+ __zypper__.refreshable.xml.call(*cmd_opt)
+
+ if call_refresh:
+ # when used with "zypper ar --refresh" or "zypper mr --refresh"
+ # --gpg-auto-import-keys is not doing anything
+ # so we need to specifically refresh here with --gpg-auto-import-keys
+ refresh_opts = global_cmd_opt + ['refresh'] + [repo]
+ __zypper__.xml.call(*refresh_opts)
+ elif not added and not cmd_opt:
raise CommandExecutionError(
'Specified arguments did not result in modification of repo'
)
diff --git a/tests/unit/modules/zypper_test.py b/tests/unit/modules/zypper_test.py
index 9ec2b83..c4f7597 100644
--- a/tests/unit/modules/zypper_test.py
+++ b/tests/unit/modules/zypper_test.py
@@ -9,7 +9,9 @@ from __future__ import absolute_import
# Import Salt Testing Libs
from salttesting import TestCase, skipIf
from salttesting.mock import (
+ Mock,
MagicMock,
+ call,
patch,
NO_MOCK,
NO_MOCK_REASON
@@ -54,10 +56,26 @@ zypper.rpm = None
@skipIf(NO_MOCK, NO_MOCK_REASON)
class ZypperTestCase(TestCase):
+
'''
Test cases for salt.modules.zypper
'''
+ def setUp(self):
+ self.new_repo_config = dict(
+ name='mock-repo-name',
+ url='http://repo.url/some/path'
+ )
+ side_effect = [
+ Mock(**{'sections.return_value': []}),
+ Mock(**{'sections.return_value': [self.new_repo_config['name']]})
+ ]
+ self.zypper_patcher_config = {
+ '_get_configured_repos': Mock(side_effect=side_effect),
+ '__zypper__': Mock(),
+ 'get_repo': Mock()
+ }
+
def test_list_upgrades(self):
'''
List package upgrades
@@ -438,6 +456,201 @@ class ZypperTestCase(TestCase):
self.assertEqual(r_info['enabled'], alias == 'SLE12-SP1-x86_64-Update')
self.assertEqual(r_info['autorefresh'], alias == 'SLE12-SP1-x86_64-Update')
+ def test_repo_add_nomod_noref(self):
+ '''
+ Test mod_repo adds the new repo and nothing else
+
+ :return:
+ '''
+ zypper_patcher = patch.multiple(
+ 'salt.modules.zypper', **self.zypper_patcher_config)
+
+ url = self.new_repo_config['url']
+ name = self.new_repo_config['name']
+ with zypper_patcher:
+ zypper.mod_repo(name, **{'url': url})
+ self.assertEqual(
+ zypper.__zypper__.xml.call.call_args_list,
+ [call('ar', url, name)]
+ )
+ zypper.__zypper__.refreshable.xml.call.assert_not_called()
+
+ def test_repo_noadd_nomod_noref(self):
+ '''
+ Test mod_repo detects the repo already exists,
+ no modification was requested and no refresh requested either
+
+ :return:
+ '''
+ url = self.new_repo_config['url']
+ name = self.new_repo_config['name']
+ self.zypper_patcher_config['_get_configured_repos'] = Mock(
+ **{'return_value.sections.return_value': [name]}
+ )
+ zypper_patcher = patch.multiple(
+ 'salt.modules.zypper', **self.zypper_patcher_config)
+
+ with zypper_patcher:
+ with self.assertRaisesRegexp(
+ Exception,
+ 'Specified arguments did not result in modification of repo'
+ ):
+ zypper.mod_repo(name, **{'url': url})
+ with self.assertRaisesRegexp(
+ Exception,
+ 'Specified arguments did not result in modification of repo'
+ ):
+ zypper.mod_repo(name, **{'url': url, 'gpgautoimport': 'a'})
+
+ zypper.__zypper__.xml.call.assert_not_called()
+ zypper.__zypper__.refreshable.xml.call.assert_not_called()
+
+ def test_repo_add_mod_noref(self):
+ '''
+ Test mod_repo adds the new repo and call modify to update autorefresh
+
+ :return:
+ '''
+ zypper_patcher = patch.multiple(
+ 'salt.modules.zypper', **self.zypper_patcher_config)
+
+ url = self.new_repo_config['url']
+ name = self.new_repo_config['name']
+ with zypper_patcher:
+ zypper.mod_repo(name, **{'url': url, 'refresh': True})
+ self.assertEqual(
+ zypper.__zypper__.xml.call.call_args_list,
+ [call('ar', url, name)]
+ )
+ zypper.__zypper__.refreshable.xml.call.assert_called_once_with(
+ 'mr', '--refresh', name
+ )
+
+ def test_repo_noadd_mod_noref(self):
+ '''
+ Test mod_repo detects the repository exists,
+ calls modify to update 'autorefresh' but does not call refresh
+
+ :return:
+ '''
+ url = self.new_repo_config['url']
+ name = self.new_repo_config['name']
+ self.zypper_patcher_config['_get_configured_repos'] = Mock(
+ **{'return_value.sections.return_value': [name]})
+ zypper_patcher = patch.multiple(
+ 'salt.modules.zypper', **self.zypper_patcher_config)
+ with zypper_patcher:
+ zypper.mod_repo(name, **{'url': url, 'refresh': True})
+ zypper.__zypper__.xml.call.assert_not_called()
+ zypper.__zypper__.refreshable.xml.call.assert_called_once_with(
+ 'mr', '--refresh', name
+ )
+
+ def test_repo_add_nomod_ref(self):
+ '''
+ Test mod_repo adds the new repo and refreshes the repo with
+ `zypper --gpg-auto-import-keys refresh <repo-name>`
+
+ :return:
+ '''
+ zypper_patcher = patch.multiple(
+ 'salt.modules.zypper', **self.zypper_patcher_config)
+
+ url = self.new_repo_config['url']
+ name = self.new_repo_config['name']
+ with zypper_patcher:
+ zypper.mod_repo(name, **{'url': url, 'gpgautoimport': True})
+ self.assertEqual(
+ zypper.__zypper__.xml.call.call_args_list,
+ [
+ call('ar', url, name),
+ call('--gpg-auto-import-keys', 'refresh', name)
+ ]
+ )
+ zypper.__zypper__.refreshable.xml.call.assert_not_called()
+
+ def test_repo_noadd_nomod_ref(self):
+ '''
+ Test mod_repo detects the repo already exists,
+ has nothing to modify and refreshes the repo with
+ `zypper --gpg-auto-import-keys refresh <repo-name>`
+
+ :return:
+ '''
+ url = self.new_repo_config['url']
+ name = self.new_repo_config['name']
+ self.zypper_patcher_config['_get_configured_repos'] = Mock(
+ **{'return_value.sections.return_value': [name]}
+ )
+ zypper_patcher = patch.multiple(
+ 'salt.modules.zypper', **self.zypper_patcher_config)
+
+ with zypper_patcher:
+ zypper.mod_repo(name, **{'url': url, 'gpgautoimport': True})
+ self.assertEqual(
+ zypper.__zypper__.xml.call.call_args_list,
+ [call('--gpg-auto-import-keys', 'refresh', name)]
+ )
+ zypper.__zypper__.refreshable.xml.call.assert_not_called()
+
+ def test_repo_add_mod_ref(self):
+ '''
+ Test mod_repo adds the new repo,
+ calls modify to update 'autorefresh' and refreshes the repo with
+ `zypper --gpg-auto-import-keys refresh <repo-name>`
+
+ :return:
+ '''
+ zypper_patcher = patch.multiple(
+ 'salt.modules.zypper', **self.zypper_patcher_config)
+
+ url = self.new_repo_config['url']
+ name = self.new_repo_config['name']
+ with zypper_patcher:
+ zypper.mod_repo(
+ name,
+ **{'url': url, 'refresh': True, 'gpgautoimport': True}
+ )
+ self.assertEqual(
+ zypper.__zypper__.xml.call.call_args_list,
+ [
+ call('ar', url, name),
+ call('--gpg-auto-import-keys', 'refresh', name)
+ ]
+ )
+ zypper.__zypper__.refreshable.xml.call.assert_called_once_with(
+ '--gpg-auto-import-keys', 'mr', '--refresh', name
+ )
+
+ def test_repo_noadd_mod_ref(self):
+ '''
+ Test mod_repo detects the repo already exists,
+ calls modify to update 'autorefresh' and refreshes the repo with
+ `zypper --gpg-auto-import-keys refresh <repo-name>`
+
+ :return:
+ '''
+ url = self.new_repo_config['url']
+ name = self.new_repo_config['name']
+ self.zypper_patcher_config['_get_configured_repos'] = Mock(
+ **{'return_value.sections.return_value': [name]}
+ )
+ zypper_patcher = patch.multiple(
+ 'salt.modules.zypper', **self.zypper_patcher_config)
+
+ with zypper_patcher:
+ zypper.mod_repo(
+ name,
+ **{'url': url, 'refresh': True, 'gpgautoimport': True}
+ )
+ self.assertEqual(
+ zypper.__zypper__.xml.call.call_args_list,
+ [call('--gpg-auto-import-keys', 'refresh', name)]
+ )
+ zypper.__zypper__.refreshable.xml.call.assert_called_once_with(
+ '--gpg-auto-import-keys', 'mr', '--refresh', name
+ )
+
if __name__ == '__main__':
from integration import run_tests
run_tests(ZypperTestCase, needs_daemon=False)
--
2.8.3

View File

@ -0,0 +1,24 @@
From af2ff55739187c59dc04e396b7787301a49a9dba Mon Sep 17 00:00:00 2001
From: Michael Calmer <mc@suse.de>
Date: Fri, 29 Jul 2016 10:50:21 +0200
Subject: [PATCH 12/12] Run salt-api as user salt (bsc#990029)
---
pkg/salt-api.service | 1 +
1 file changed, 1 insertion(+)
diff --git a/pkg/salt-api.service b/pkg/salt-api.service
index 72379ba..9be2cb8 100644
--- a/pkg/salt-api.service
+++ b/pkg/salt-api.service
@@ -3,6 +3,7 @@ Description=The Salt API
After=network.target
[Service]
+User=salt
Type=simple
LimitNOFILE=8192
ExecStart=/usr/bin/salt-api
--
2.9.2

View File

@ -0,0 +1,25 @@
From d19c9591c1dfbafec24a7d76402dcc9e2b17b047 Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Thu, 4 Aug 2016 11:28:19 +0200
Subject: [PATCH 13/13] Deprecate status.uptime one version later
---
salt/modules/status.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/salt/modules/status.py b/salt/modules/status.py
index 029426b..cebd57b 100644
--- a/salt/modules/status.py
+++ b/salt/modules/status.py
@@ -132,7 +132,7 @@ def custom():
return ret
-@with_deprecated(globals(), "Boron")
+@with_deprecated(globals(), "Carbon")
def uptime():
'''
Return the uptime for this system.
--
2.9.2

View File

@ -0,0 +1,82 @@
From f860f7ccb3dba6b8f0cef61e2d9658a3116e3c3c Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Mon, 15 Aug 2016 15:03:53 +0200
Subject: [PATCH 14/15] Add ignore_repo_failure option to suppress zypper's
exit code 106 on unavailable repos
---
salt/modules/zypper.py | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index 547d72b..1c60f0f 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -100,6 +100,18 @@ class _Zypper(object):
self.__no_lock = False
self.__no_raise = False
self.__refresh = False
+ self.__ignore_repo_failure = False
+
+ def __call__(self, *args, **kwargs):
+ '''
+ :param args:
+ :param kwargs:
+ :return:
+ '''
+ # Ignore exit code for 106 (repo is not available)
+ if 'no_repo_failure' in kwargs:
+ self.__ignore_repo_failure = kwargs['no_repo_failure']
+ return self
def __getattr__(self, item):
'''
@@ -275,7 +287,7 @@ class _Zypper(object):
__salt__['event.fire_master']({'success': not len(self.error_msg),
'info': self.error_msg or 'Zypper has been released'},
self.TAG_RELEASED)
- if self.error_msg and not self.__no_raise:
+ if self.error_msg and not self.__no_raise and not self.__ignore_repo_failure:
raise CommandExecutionError('Zypper command failure: {0}'.format(self.error_msg))
return self._is_xml_mode() and dom.parseString(self.__call_result['stdout']) or self.__call_result['stdout']
@@ -863,6 +875,7 @@ def install(name=None,
downloadonly=None,
skip_verify=False,
version=None,
+ ignore_repo_failure=False,
**kwargs):
'''
Install the passed package(s), add refresh=True to force a 'zypper refresh'
@@ -929,6 +942,10 @@ def install(name=None,
salt '*' pkg.install sources='[{"foo": "salt://foo.rpm"},{"bar": "salt://bar.rpm"}]'
+ ignore_repo_failure
+ Zypper returns error code 106 if one of the repositories are not available for various reasons.
+ In case to set strict check, this parameter needs to be set to True. Default: False.
+
Returns a dict containing the new package names and versions::
@@ -1000,7 +1017,7 @@ def install(name=None,
while targets:
cmd = cmd_install + targets[:500]
targets = targets[500:]
- for line in __zypper__.call(*cmd).splitlines():
+ for line in __zypper__(no_repo_failure=ignore_repo_failure).call(*cmd).splitlines():
match = re.match(r"^The selected package '([^']+)'.+has lower version", line)
if match:
downgrades.append(match.group(1))
@@ -1008,7 +1025,7 @@ def install(name=None,
while downgrades:
cmd = cmd_install + ['--force'] + downgrades[:500]
downgrades = downgrades[500:]
- __zypper__.call(*cmd)
+ __zypper__(no_repo_failure=ignore_repo_failure).call(*cmd)
__context__.pop('pkg.list_pkgs', None)
new = list_pkgs()
--
2.9.3

View File

@ -0,0 +1,78 @@
From 0809c60c693eb5d2e9569c24d995818097c6920d Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Mon, 15 Aug 2016 17:35:01 +0200
Subject: [PATCH 15/15] Remove zypper's raise exception if mod_repo has no
arguments and/or no changes
* Fix Unit test for suppressing the exception removal on non-modified repos
---
salt/modules/zypper.py | 11 +++++++----
tests/unit/modules/zypper_test.py | 15 +++------------
2 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index 1c60f0f..1ec903e 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -824,6 +824,7 @@ def mod_repo(repo, **kwargs):
cmd_opt = global_cmd_opt + ['mr'] + cmd_opt + [repo]
__zypper__.refreshable.xml.call(*cmd_opt)
+ comment = None
if call_refresh:
# when used with "zypper ar --refresh" or "zypper mr --refresh"
# --gpg-auto-import-keys is not doing anything
@@ -831,11 +832,13 @@ def mod_repo(repo, **kwargs):
refresh_opts = global_cmd_opt + ['refresh'] + [repo]
__zypper__.xml.call(*refresh_opts)
elif not added and not cmd_opt:
- raise CommandExecutionError(
- 'Specified arguments did not result in modification of repo'
- )
+ comment = 'Specified arguments did not result in modification of repo'
+
+ repo = get_repo(repo)
+ if comment:
+ repo['comment'] = comment
- return get_repo(repo)
+ return repo
def refresh_db():
diff --git a/tests/unit/modules/zypper_test.py b/tests/unit/modules/zypper_test.py
index 2f2b323..7caa707 100644
--- a/tests/unit/modules/zypper_test.py
+++ b/tests/unit/modules/zypper_test.py
@@ -73,7 +73,7 @@ class ZypperTestCase(TestCase):
self.zypper_patcher_config = {
'_get_configured_repos': Mock(side_effect=side_effect),
'__zypper__': Mock(),
- 'get_repo': Mock()
+ 'get_repo': Mock(return_value={})
}
def test_list_upgrades(self):
@@ -493,17 +493,8 @@ class ZypperTestCase(TestCase):
'salt.modules.zypper', **self.zypper_patcher_config)
with zypper_patcher:
- with self.assertRaisesRegexp(
- Exception,
- 'Specified arguments did not result in modification of repo'
- ):
- zypper.mod_repo(name, **{'url': url})
- with self.assertRaisesRegexp(
- Exception,
- 'Specified arguments did not result in modification of repo'
- ):
- zypper.mod_repo(name, **{'url': url, 'gpgautoimport': 'a'})
-
+ self.assertEqual(zypper.mod_repo(name, **{'url': url}),
+ {'comment': 'Specified arguments did not result in modification of repo'})
zypper.__zypper__.xml.call.assert_not_called()
zypper.__zypper__.refreshable.xml.call.assert_not_called()
--
2.9.3

View File

@ -0,0 +1,83 @@
From 50865e300e6e90c5cc80c8878949a2f3bcaaeeec Mon Sep 17 00:00:00 2001
From: Bo Maryniuk <bo@suse.de>
Date: Thu, 25 Aug 2016 16:47:08 +0200
Subject: [PATCH 16/16] Improve Mock to be flexible and able to mock methods
from the mocked modules
* Configure importing Mock to handle 'total' method from psutils properly
---
doc/conf.py | 37 +++++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/doc/conf.py b/doc/conf.py
index 9cefed8..b73ca2a 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -15,31 +15,40 @@ from sphinx.directives import TocTree
# pylint: disable=R0903
class Mock(object):
'''
- Mock out specified imports
+ Mock out specified imports.
This allows autodoc to do its thing without having oodles of req'd
installed libs. This doesn't work with ``import *`` imports.
+ This Mock class can be configured to return a specific values at specific names, if required.
+
http://read-the-docs.readthedocs.org/en/latest/faq.html#i-get-import-errors-on-libraries-that-depend-on-c-modules
'''
- def __init__(self, *args, **kwargs):
- pass
+ def __init__(self, mapping=None, *args, **kwargs):
+ """
+ Mapping allows to bypass the Mock object, but actually assign
+ a specific value, expected by a specific attribute returned.
+ """
+ self.__mapping = mapping or {}
__all__ = []
def __call__(self, *args, **kwargs):
- ret = Mock()
# If mocked function is used as a decorator, expose decorated function.
# if args and callable(args[-1]):
# functools.update_wrapper(ret, args[0])
- return ret
-
- @classmethod
- def __getattr__(cls, name):
- if name in ('__file__', '__path__'):
- return '/dev/null'
+ return Mock(mapping=self.__mapping)
+
+ def __getattr__(self, name):
+ #__mapping = {'total': 0}
+ data = None
+ if name in self.__mapping:
+ data = self.__mapping.get(name)
+ elif name in ('__file__', '__path__'):
+ data = '/dev/null'
else:
- return Mock()
+ data = Mock(mapping=self.__mapping)
+ return data
# pylint: enable=R0903
MOCK_MODULES = [
@@ -133,7 +142,11 @@ MOCK_MODULES = [
]
for mod_name in MOCK_MODULES:
- sys.modules[mod_name] = Mock()
+ if mod_name == 'psutil':
+ mock = Mock(mapping={'total': 0}) # Otherwise it will crash Sphinx
+ else:
+ mock = Mock()
+ sys.modules[mod_name] = mock
def mock_decorator_with_params(*oargs, **okwargs):
'''
--
2.9.3

View File

@ -0,0 +1,35 @@
From e9b4a199f48abc94be71082c56b6b059c6694dc0 Mon Sep 17 00:00:00 2001
From: Eric Jackson <swiftgist@gmail.com>
Date: Tue, 30 Aug 2016 15:47:07 -0400
Subject: [PATCH 17/17] Check for single quote before splitting on single quote
Signed-off-by: Eric Jackson <ejackson@suse.com>
Lint for #35916
Merges #35916
---
salt/modules/zypper.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
index 1ec903e..4bb9a09 100644
--- a/salt/modules/zypper.py
+++ b/salt/modules/zypper.py
@@ -859,11 +859,11 @@ def refresh_db():
for line in out.splitlines():
if not line:
continue
- if line.strip().startswith('Repository'):
+ if line.strip().startswith('Repository') and '\'' in line:
key = line.split('\'')[1].strip()
if 'is up to date' in line:
ret[key] = False
- elif line.strip().startswith('Building'):
+ elif line.strip().startswith('Building') and '\'' in line:
key = line.split('\'')[1].strip()
if 'done' in line:
ret[key] = True
--
2.8.2

View File

@ -0,0 +1,927 @@
From e5fc36b5fad0683f57022bf2f3c63f453cda5e8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
<psuarezhernandez@suse.com>
Date: Tue, 6 Sep 2016 11:21:05 +0100
Subject: [PATCH 18/19] Unit tests fixes for 2016.3.2
* Fixing skipped boto tests to prevent errors if boto3 does not exists.
* Fix tests that assert CommandExecutionError (#32485)
Trying to assert that an exception was raised using
helper_open.write.assertRaises() is bogus--there is no such method. Use
standard unittest.assertRaises() instead.
* Skip utils_test if timelib is not installed (#32699)
date_cast() throws a RuntimeError, not an ImportError
* Fix tests (#35693)
Fix tests/unit/modules/useradd_test.py::UserAddTestCase::test_info
Fix unit/pyobjects_test.py::MapTests::test_map
Fix tests/unit/pyobjects_test.py::RendererTests::test_extend
Fix tests/unit/pyobjects_test.py::RendererTests::test_requisite_implicit_list
* Fix tests to prevent errors when libcloud is not present
* Fixed _interfaces_ifconfig output for SunOS test
* Fix PortageConfigTestCase in case of portage is not present
* Rename dockerio.py unit tests to dockerio_test.py
These tests have never run automatically because of an incorrect file name.
Added a skipIf on these tests as they are currently non-functioning and the
module they're testing has been deprecated.
* Prevent tests failures if boto does not exists
---
salt/modules/boto_elb.py | 2 +-
salt/modules/linux_sysctl.py | 6 +-
tests/unit/cloud/clouds/dimensiondata_test.py | 10 ++-
tests/unit/cloud/clouds/gce_test.py | 10 ++-
tests/unit/modules/boto_cloudtrail_test.py | 10 +--
tests/unit/modules/boto_iot_test.py | 10 +--
tests/unit/modules/boto_lambda_test.py | 10 +--
tests/unit/modules/boto_s3_bucket_test.py | 10 +--
tests/unit/modules/boto_secgroup_test.py | 1 +
tests/unit/modules/boto_vpc_test.py | 14 ++--
tests/unit/modules/linux_sysctl_test.py | 19 +++--
tests/unit/modules/mac_sysctl_test.py | 10 +--
tests/unit/modules/mount_test.py | 14 ++--
tests/unit/modules/portage_config.py | 10 ++-
tests/unit/modules/puppet_test.py | 15 ++--
tests/unit/modules/useradd_test.py | 6 +-
tests/unit/pyobjects_test.py | 11 +++
tests/unit/states/boto_cloudtrail_test.py | 10 +--
tests/unit/states/boto_iot_test.py | 10 +--
tests/unit/states/boto_lambda_test.py | 10 +--
tests/unit/states/boto_s3_bucket_test.py | 10 +--
tests/unit/states/dockerio.py | 112 -------------------------
tests/unit/states/dockerio_test.py | 113 ++++++++++++++++++++++++++
tests/unit/utils/network.py | 12 +--
tests/unit/utils/utils_test.py | 11 +--
25 files changed, 244 insertions(+), 212 deletions(-)
delete mode 100644 tests/unit/states/dockerio.py
create mode 100644 tests/unit/states/dockerio_test.py
diff --git a/salt/modules/boto_elb.py b/salt/modules/boto_elb.py
index 31df1fc..162abcd 100644
--- a/salt/modules/boto_elb.py
+++ b/salt/modules/boto_elb.py
@@ -57,6 +57,7 @@ log = logging.getLogger(__name__)
# Import third party libs
try:
import boto
+ import boto.ec2 # pylint: enable=unused-import
# connection settings were added in 2.33.0
required_boto_version = '2.33.0'
if (_LooseVersion(boto.__version__) <
@@ -64,7 +65,6 @@ try:
msg = 'boto_elb requires boto {0}.'.format(required_boto_version)
logging.debug(msg)
raise ImportError()
- import boto.ec2
from boto.ec2.elb import HealthCheck
from boto.ec2.elb.attributes import AccessLogAttribute
from boto.ec2.elb.attributes import ConnectionDrainingAttribute
diff --git a/salt/modules/linux_sysctl.py b/salt/modules/linux_sysctl.py
index b016ca6..7702d52 100644
--- a/salt/modules/linux_sysctl.py
+++ b/salt/modules/linux_sysctl.py
@@ -41,7 +41,11 @@ def _check_systemd_salt_config():
sysctl_dir = os.path.split(conf)[0]
if not os.path.exists(sysctl_dir):
os.makedirs(sysctl_dir)
- salt.utils.fopen(conf, 'w').close()
+ try:
+ salt.utils.fopen(conf, 'w').close()
+ except (IOError, OSError):
+ msg = 'Could not create file: {0}'
+ raise CommandExecutionError(msg.format(conf))
return conf
diff --git a/tests/unit/cloud/clouds/dimensiondata_test.py b/tests/unit/cloud/clouds/dimensiondata_test.py
index aa7f2c0..ee01d65 100644
--- a/tests/unit/cloud/clouds/dimensiondata_test.py
+++ b/tests/unit/cloud/clouds/dimensiondata_test.py
@@ -8,7 +8,13 @@
# Import Python libs
from __future__ import absolute_import
-import libcloud.security
+
+try:
+ import libcloud.security
+ HAS_LIBCLOUD = True
+except ImportError:
+ HAS_LIBCLOUD = False
+
import platform
import os
@@ -44,7 +50,7 @@ ON_SUSE = True if 'SuSE' in platform.dist() else False
ON_MAC = True if 'Darwin' in platform.system() else False
if not os.path.exists('/etc/ssl/certs/YaST-CA.pem') and ON_SUSE:
- if os.path.isfile('/etc/ssl/ca-bundle.pem'):
+ if os.path.isfile('/etc/ssl/ca-bundle.pem') and HAS_LIBCLOUD:
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/ca-bundle.pem')
else:
HAS_CERTS = False
diff --git a/tests/unit/cloud/clouds/gce_test.py b/tests/unit/cloud/clouds/gce_test.py
index 87824eb..c90f8ab 100644
--- a/tests/unit/cloud/clouds/gce_test.py
+++ b/tests/unit/cloud/clouds/gce_test.py
@@ -8,7 +8,13 @@
# Import Python libs
from __future__ import absolute_import
-import libcloud.security
+
+try:
+ import libcloud.security
+ HAS_LIBCLOUD = True
+except ImportError:
+ HAS_LIBCLOUD = False
+
import platform
import os
@@ -51,7 +57,7 @@ ON_SUSE = True if 'SuSE' in platform.dist() else False
ON_MAC = True if 'Darwin' in platform.system() else False
if not os.path.exists('/etc/ssl/certs/YaST-CA.pem') and ON_SUSE:
- if os.path.isfile('/etc/ssl/ca-bundle.pem'):
+ if os.path.isfile('/etc/ssl/ca-bundle.pem') and HAS_LIBCLOUD:
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/ca-bundle.pem')
else:
HAS_CERTS = False
diff --git a/tests/unit/modules/boto_cloudtrail_test.py b/tests/unit/modules/boto_cloudtrail_test.py
index 2f86101..264a795 100644
--- a/tests/unit/modules/boto_cloudtrail_test.py
+++ b/tests/unit/modules/boto_cloudtrail_test.py
@@ -103,6 +103,11 @@ if _has_required_boto():
StopLoggingTime=None)
+@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
+@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
+ ' or equal to version {0}'
+ .format(required_boto3_version))
+@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoCloudTrailTestCaseBase(TestCase):
conn = None
@@ -128,11 +133,6 @@ class BotoCloudTrailTestCaseMixin(object):
pass
-@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
-@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
- ' or equal to version {0}'
- .format(required_boto3_version))
-@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoCloudTrailTestCase(BotoCloudTrailTestCaseBase, BotoCloudTrailTestCaseMixin):
'''
TestCase for salt.modules.boto_cloudtrail module
diff --git a/tests/unit/modules/boto_iot_test.py b/tests/unit/modules/boto_iot_test.py
index 73c362f..520bfe9 100644
--- a/tests/unit/modules/boto_iot_test.py
+++ b/tests/unit/modules/boto_iot_test.py
@@ -103,6 +103,11 @@ if _has_required_boto():
ruleDisabled=True)
+@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
+@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
+ ' or equal to version {0}'
+ .format(required_boto3_version))
+@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoIoTTestCaseBase(TestCase):
conn = None
@@ -128,11 +133,6 @@ class BotoIoTTestCaseMixin(object):
pass
-@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
-@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
- ' or equal to version {0}'
- .format(required_boto3_version))
-@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoIoTPolicyTestCase(BotoIoTTestCaseBase, BotoIoTTestCaseMixin):
'''
TestCase for salt.modules.boto_iot module
diff --git a/tests/unit/modules/boto_lambda_test.py b/tests/unit/modules/boto_lambda_test.py
index 01ca245..ad7fb33 100644
--- a/tests/unit/modules/boto_lambda_test.py
+++ b/tests/unit/modules/boto_lambda_test.py
@@ -109,6 +109,11 @@ def _has_required_boto():
return True
+@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
+@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
+ ' or equal to version {0}'
+ .format(required_boto3_version))
+@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoLambdaTestCaseBase(TestCase):
conn = None
@@ -145,11 +150,6 @@ class BotoLambdaTestCaseMixin(object):
pass
-@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
-@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
- ' or equal to version {0}'
- .format(required_boto3_version))
-@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoLambdaFunctionTestCase(BotoLambdaTestCaseBase, BotoLambdaTestCaseMixin):
'''
TestCase for salt.modules.boto_lambda module
diff --git a/tests/unit/modules/boto_s3_bucket_test.py b/tests/unit/modules/boto_s3_bucket_test.py
index f4b1992..5e7d6be 100644
--- a/tests/unit/modules/boto_s3_bucket_test.py
+++ b/tests/unit/modules/boto_s3_bucket_test.py
@@ -205,6 +205,11 @@ if _has_required_boto():
}
+@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
+@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
+ ' or equal to version {0}'
+ .format(required_boto3_version))
+@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoS3BucketTestCaseBase(TestCase):
conn = None
@@ -230,11 +235,6 @@ class BotoS3BucketTestCaseMixin(object):
pass
-@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
-@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
- ' or equal to version {0}'
- .format(required_boto3_version))
-@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoS3BucketTestCase(BotoS3BucketTestCaseBase, BotoS3BucketTestCaseMixin):
'''
TestCase for salt.modules.boto_s3_bucket module
diff --git a/tests/unit/modules/boto_secgroup_test.py b/tests/unit/modules/boto_secgroup_test.py
index cc88568..7fd51ad 100644
--- a/tests/unit/modules/boto_secgroup_test.py
+++ b/tests/unit/modules/boto_secgroup_test.py
@@ -23,6 +23,7 @@ import salt.loader
from salt.ext.six.moves import range # pylint: disable=redefined-builtin
try:
import boto
+ import boto.ec2 # pylint: enable=unused-import
HAS_BOTO = True
except ImportError:
HAS_BOTO = False
diff --git a/tests/unit/modules/boto_vpc_test.py b/tests/unit/modules/boto_vpc_test.py
index 64c7976..162bcae 100644
--- a/tests/unit/modules/boto_vpc_test.py
+++ b/tests/unit/modules/boto_vpc_test.py
@@ -124,6 +124,13 @@ def _has_required_moto():
context = {}
+@skipIf(NO_MOCK, NO_MOCK_REASON)
+@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
+@skipIf(HAS_MOTO is False, 'The moto module must be installed.')
+@skipIf(_has_required_boto() is False, 'The boto module must be greater than'
+ ' or equal to version {0}'
+ .format(required_boto_version))
+@skipIf(_has_required_moto() is False, 'The moto version must be >= to version {0}'.format(required_moto_version))
class BotoVpcTestCaseBase(TestCase):
def setUp(self):
boto_vpc.__context__ = {}
@@ -249,13 +256,6 @@ class BotoVpcTestCaseMixin(object):
return rtbl
-@skipIf(NO_MOCK, NO_MOCK_REASON)
-@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
-@skipIf(HAS_MOTO is False, 'The moto module must be installed.')
-@skipIf(_has_required_boto() is False, 'The boto module must be greater than'
- ' or equal to version {0}'
- .format(required_boto_version))
-@skipIf(_has_required_moto() is False, 'The moto version must be >= to version {0}'.format(required_moto_version))
class BotoVpcTestCase(BotoVpcTestCaseBase, BotoVpcTestCaseMixin):
'''
TestCase for salt.modules.boto_vpc module
diff --git a/tests/unit/modules/linux_sysctl_test.py b/tests/unit/modules/linux_sysctl_test.py
index 89bea83..1eca7d5 100644
--- a/tests/unit/modules/linux_sysctl_test.py
+++ b/tests/unit/modules/linux_sysctl_test.py
@@ -84,17 +84,22 @@ class LinuxSysctlTestCase(TestCase):
self.assertEqual(linux_sysctl.assign(
'net.ipv4.ip_forward', 1), ret)
- @patch('os.path.isfile', MagicMock(return_value=False))
def test_persist_no_conf_failure(self):
'''
Tests adding of config file failure
'''
- with patch('salt.utils.fopen', mock_open()) as m_open:
- helper_open = m_open()
- helper_open.write.assertRaises(CommandExecutionError,
- linux_sysctl.persist,
- 'net.ipv4.ip_forward',
- 1, config=None)
+ asn_cmd = {'pid': 1337, 'retcode': 0,
+ 'stderr': "sysctl: permission denied", 'stdout': ''}
+ mock_asn_cmd = MagicMock(return_value=asn_cmd)
+ cmd = "sysctl -w net.ipv4.ip_forward=1"
+ mock_cmd = MagicMock(return_value=cmd)
+ with patch.dict(linux_sysctl.__salt__, {'cmd.run_stdout': mock_cmd,
+ 'cmd.run_all': mock_asn_cmd}):
+ with patch('salt.utils.fopen', mock_open()) as m_open:
+ self.assertRaises(CommandExecutionError,
+ linux_sysctl.persist,
+ 'net.ipv4.ip_forward',
+ 1, config=None)
@patch('os.path.isfile', MagicMock(return_value=False))
@patch('os.path.exists', MagicMock(return_value=True))
diff --git a/tests/unit/modules/mac_sysctl_test.py b/tests/unit/modules/mac_sysctl_test.py
index e90ec64..533397b 100644
--- a/tests/unit/modules/mac_sysctl_test.py
+++ b/tests/unit/modules/mac_sysctl_test.py
@@ -72,11 +72,11 @@ class DarwinSysctlTestCase(TestCase):
Tests adding of config file failure
'''
with patch('salt.utils.fopen', mock_open()) as m_open:
- helper_open = m_open()
- helper_open.write.assertRaises(CommandExecutionError,
- mac_sysctl.persist,
- 'net.inet.icmp.icmplim',
- 50, config=None)
+ m_open.side_effect = IOError(13, 'Permission denied', '/file')
+ self.assertRaises(CommandExecutionError,
+ mac_sysctl.persist,
+ 'net.inet.icmp.icmplim',
+ 50, config=None)
@patch('os.path.isfile', MagicMock(return_value=False))
def test_persist_no_conf_success(self):
diff --git a/tests/unit/modules/mount_test.py b/tests/unit/modules/mount_test.py
index 290c368..b2cf904 100644
--- a/tests/unit/modules/mount_test.py
+++ b/tests/unit/modules/mount_test.py
@@ -141,10 +141,10 @@ class MountTestCase(TestCase):
with patch.dict(mount.__grains__, {'kernel': ''}):
with patch.object(mount, 'fstab', mock_fstab):
with patch('salt.utils.fopen', mock_open()) as m_open:
- helper_open = m_open()
- helper_open.write.assertRaises(CommandExecutionError,
- mount.rm_fstab,
- config=None)
+ m_open.side_effect = IOError(13, 'Permission denied:', '/file')
+ self.assertRaises(CommandExecutionError,
+ mount.rm_fstab,
+ 'name', 'device')
def test_set_fstab(self):
'''
@@ -180,11 +180,7 @@ class MountTestCase(TestCase):
mock = MagicMock(return_value={'name': 'name'})
with patch.object(mount, 'fstab', mock):
- with patch('salt.utils.fopen', mock_open()) as m_open:
- helper_open = m_open()
- helper_open.write.assertRaises(CommandExecutionError,
- mount.rm_automaster,
- 'name', 'device')
+ self.assertTrue(mount.rm_automaster('name', 'device'))
def test_set_automaster(self):
'''
diff --git a/tests/unit/modules/portage_config.py b/tests/unit/modules/portage_config.py
index 8da1ebe..6275442 100644
--- a/tests/unit/modules/portage_config.py
+++ b/tests/unit/modules/portage_config.py
@@ -11,7 +11,7 @@ from __future__ import absolute_import
# Import Salt Testing libs
from salttesting import skipIf, TestCase
from salttesting.helpers import ensure_in_syspath
-from salttesting.mock import NO_MOCK, NO_MOCK_REASON
+from salttesting.mock import NO_MOCK, NO_MOCK_REASON, MagicMock
ensure_in_syspath('../../')
# Import salt libs
@@ -20,6 +20,10 @@ from salt.modules import portage_config
@skipIf(NO_MOCK, NO_MOCK_REASON)
class PortageConfigTestCase(TestCase):
+ class DummyAtom(object):
+ def __init__(self, atom):
+ self.cp, self.repo = atom.split("::") if "::" in atom else (atom, None)
+
def test_get_config_file_wildcards(self):
pairs = [
('*/*::repo', '/etc/portage/package.mask/repo'),
@@ -29,7 +33,11 @@ class PortageConfigTestCase(TestCase):
('cat/pkg::repo', '/etc/portage/package.mask/cat/pkg'),
]
+ portage_config.portage = MagicMock()
for (atom, expected) in pairs:
+ dummy_atom = self.DummyAtom(atom)
+ portage_config.portage.dep.Atom = MagicMock(return_value=dummy_atom)
+ portage_config._p_to_cp = MagicMock(return_value=dummy_atom.cp)
self.assertEqual(portage_config._get_config_file('mask', atom), expected)
if __name__ == '__main__':
diff --git a/tests/unit/modules/puppet_test.py b/tests/unit/modules/puppet_test.py
index 02bc2e1..2cdd696 100644
--- a/tests/unit/modules/puppet_test.py
+++ b/tests/unit/modules/puppet_test.py
@@ -85,10 +85,12 @@ class PuppetTestCase(TestCase):
with patch('salt.utils.fopen', mock_open()):
self.assertTrue(puppet.disable())
- with patch('salt.utils.fopen', mock_open()) as m_open:
- helper_open = m_open()
- helper_open.write.assertRaises(CommandExecutionError,
- puppet.disable)
+ try:
+ with patch('salt.utils.fopen', mock_open()) as m_open:
+ m_open.side_effect = IOError(13, 'Permission denied:', '/file')
+ self.assertRaises(CommandExecutionError, puppet.disable)
+ except StopIteration:
+ pass
def test_status(self):
'''
@@ -145,9 +147,8 @@ class PuppetTestCase(TestCase):
self.assertDictEqual(puppet.summary(), {'resources': 1})
with patch('salt.utils.fopen', mock_open()) as m_open:
- helper_open = m_open()
- helper_open.write.assertRaises(CommandExecutionError,
- puppet.summary)
+ m_open.side_effect = IOError(13, 'Permission denied:', '/file')
+ self.assertRaises(CommandExecutionError, puppet.summary)
def test_plugin_sync(self):
'''
diff --git a/tests/unit/modules/useradd_test.py b/tests/unit/modules/useradd_test.py
index 7e646b6..cc9e610 100644
--- a/tests/unit/modules/useradd_test.py
+++ b/tests/unit/modules/useradd_test.py
@@ -326,7 +326,7 @@ class UserAddTestCase(TestCase):
'''
Test the user information
'''
- self.assertEqual(useradd.info('salt'), {})
+ self.assertEqual(useradd.info('username-that-doesnt-exist'), {})
mock = MagicMock(return_value=pwd.struct_passwd(('_TEST_GROUP',
'*',
@@ -336,9 +336,7 @@ class UserAddTestCase(TestCase):
'/var/virusmails',
'/usr/bin/false')))
with patch.object(pwd, 'getpwnam', mock):
- mock = MagicMock(return_value='Group Name')
- with patch.object(useradd, 'list_groups', mock):
- self.assertEqual(useradd.info('salt')['name'], '_TEST_GROUP')
+ self.assertEqual(useradd.info('username-that-doesnt-exist')['name'], '_TEST_GROUP')
# 'list_groups' function tests: 1
diff --git a/tests/unit/pyobjects_test.py b/tests/unit/pyobjects_test.py
index f1c3e29..3eb4bd5 100644
--- a/tests/unit/pyobjects_test.py
+++ b/tests/unit/pyobjects_test.py
@@ -54,10 +54,18 @@ include('http')
extend_template = '''#!pyobjects
include('http')
+
+from salt.utils.pyobjects import StateFactory
+Service = StateFactory('service')
+
Service.running(extend('apache'), watch=[{'file': '/etc/file'}])
'''
map_template = '''#!pyobjects
+from salt.utils.pyobjects import StateFactory
+Service = StateFactory('service')
+
+
class Samba(Map):
__merge__ = 'samba:lookup'
@@ -127,6 +135,9 @@ from salt://password.sls import password
'''
requisite_implicit_list_template = '''#!pyobjects
+from salt.utils.pyobjects import StateFactory
+Service = StateFactory('service')
+
with Pkg.installed("pkg"):
Service.running("service", watch=File("file"), require=Cmd("cmd"))
'''
diff --git a/tests/unit/states/boto_cloudtrail_test.py b/tests/unit/states/boto_cloudtrail_test.py
index 48fbd32..9e6dd95 100644
--- a/tests/unit/states/boto_cloudtrail_test.py
+++ b/tests/unit/states/boto_cloudtrail_test.py
@@ -104,6 +104,11 @@ if _has_required_boto():
StopLoggingTime=None)
+@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
+@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
+ ' or equal to version {0}'
+ .format(required_boto3_version))
+@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoCloudTrailStateTestCaseBase(TestCase):
conn = None
@@ -124,11 +129,6 @@ class BotoCloudTrailStateTestCaseBase(TestCase):
session_instance.client.return_value = self.conn
-@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
-@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
- ' or equal to version {0}'
- .format(required_boto3_version))
-@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoCloudTrailTestCase(BotoCloudTrailStateTestCaseBase, BotoCloudTrailTestCaseMixin):
'''
TestCase for salt.modules.boto_cloudtrail state.module
diff --git a/tests/unit/states/boto_iot_test.py b/tests/unit/states/boto_iot_test.py
index 8c2549d..81d68c8 100644
--- a/tests/unit/states/boto_iot_test.py
+++ b/tests/unit/states/boto_iot_test.py
@@ -103,6 +103,11 @@ if _has_required_boto():
principal = 'arn:aws:iot:us-east-1:1234:cert/21fc104aaaf6043f5756c1b57bda84ea8395904c43f28517799b19e4c42514'
+@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
+@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
+ ' or equal to version {0}'
+ .format(required_boto3_version))
+@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoIoTStateTestCaseBase(TestCase):
conn = None
@@ -123,11 +128,6 @@ class BotoIoTStateTestCaseBase(TestCase):
session_instance.client.return_value = self.conn
-@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
-@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
- ' or equal to version {0}'
- .format(required_boto3_version))
-@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoIoTPolicyTestCase(BotoIoTStateTestCaseBase, BotoIoTTestCaseMixin):
'''
TestCase for salt.modules.boto_iot state.module
diff --git a/tests/unit/states/boto_lambda_test.py b/tests/unit/states/boto_lambda_test.py
index 4557aed..7b02391 100644
--- a/tests/unit/states/boto_lambda_test.py
+++ b/tests/unit/states/boto_lambda_test.py
@@ -101,6 +101,11 @@ def _has_required_boto():
return True
+@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
+@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
+ ' or equal to version {0}'
+ .format(required_boto3_version))
+@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoLambdaStateTestCaseBase(TestCase):
conn = None
@@ -121,11 +126,6 @@ class BotoLambdaStateTestCaseBase(TestCase):
session_instance.client.return_value = self.conn
-@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
-@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
- ' or equal to version {0}'
- .format(required_boto3_version))
-@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoLambdaFunctionTestCase(BotoLambdaStateTestCaseBase, BotoLambdaTestCaseMixin):
'''
TestCase for salt.modules.boto_lambda state.module
diff --git a/tests/unit/states/boto_s3_bucket_test.py b/tests/unit/states/boto_s3_bucket_test.py
index 4049e9a..03c406f 100644
--- a/tests/unit/states/boto_s3_bucket_test.py
+++ b/tests/unit/states/boto_s3_bucket_test.py
@@ -277,6 +277,11 @@ if _has_required_boto():
}
+@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
+@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
+ ' or equal to version {0}'
+ .format(required_boto3_version))
+@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoS3BucketStateTestCaseBase(TestCase):
conn = None
@@ -297,11 +302,6 @@ class BotoS3BucketStateTestCaseBase(TestCase):
session_instance.client.return_value = self.conn
-@skipIf(HAS_BOTO is False, 'The boto module must be installed.')
-@skipIf(_has_required_boto() is False, 'The boto3 module must be greater than'
- ' or equal to version {0}'
- .format(required_boto3_version))
-@skipIf(NO_MOCK, NO_MOCK_REASON)
class BotoS3BucketTestCase(BotoS3BucketStateTestCaseBase, BotoS3BucketTestCaseMixin):
'''
TestCase for salt.modules.boto_s3_bucket state.module
diff --git a/tests/unit/states/dockerio.py b/tests/unit/states/dockerio.py
deleted file mode 100644
index c73b633..0000000
--- a/tests/unit/states/dockerio.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Import Python libs
-from __future__ import absolute_import
-from contextlib import contextmanager
-
-# Import Salt Testing libs
-from salttesting import skipIf, TestCase
-from salttesting.mock import NO_MOCK, NO_MOCK_REASON, MagicMock
-
-
-@contextmanager
-def provision_state(module, fixture):
- previous_dict = getattr(module, '__salt__', {}).copy()
- try:
- module.__dict__.setdefault('__salt__', {}).update(fixture)
- yield
- finally:
- setattr(module, '__salt__', previous_dict)
-
-
-@skipIf(NO_MOCK, NO_MOCK_REASON)
-class DockerStateTestCase(TestCase):
- def test_docker_run_success(self):
- from salt.states import dockerio
- salt_fixture = {'docker.retcode': MagicMock(return_value=0),
- 'docker.run_all': MagicMock(
- return_value={'stdout': '.\n..\n',
- 'stderr': '',
- 'status': True,
- 'comment': 'Success',
- 'retcode': 0})}
-
- with provision_state(dockerio, salt_fixture):
- result = dockerio.run('ls /', 'ubuntu')
-
- self.assertEqual(result, {'name': 'ls /',
- 'result': True,
- 'comment': 'Success',
- 'changes': {}})
-
- def test_docker_run_failure(self):
- from salt.states import dockerio
- salt_fixture = {'docker.retcode': MagicMock(return_value=0),
- 'docker.run_all': MagicMock(
- return_value={'stdout': '',
- 'stderr': 'Error',
- 'status': False,
- 'comment': 'Failure',
- 'retcode': 1})}
-
- with provision_state(dockerio, salt_fixture):
- result = dockerio.run('ls /', 'ubuntu')
-
- self.assertEqual(result, {'name': 'ls /',
- 'result': False,
- 'comment': 'Failure',
- 'changes': {}})
-
- def test_docker_run_onlyif(self):
- from salt.states import dockerio
- salt_fixture = {'docker.retcode': MagicMock(return_value=1),
- 'docker.run_all': None}
- with provision_state(dockerio, salt_fixture):
- result = dockerio.run('ls /', 'ubuntu',
- onlyif='ls -l')
- self.assertEqual(result, {'name': 'ls /',
- 'result': True,
- 'comment': 'onlyif execution failed',
- 'changes': {}})
-
- def test_docker_run_unless(self):
- from salt.states import dockerio
- salt_fixture = {'docker.retcode': MagicMock(return_value=0),
- 'docker.run_all': None}
- with provision_state(dockerio, salt_fixture):
- result = dockerio.run('ls /', 'ubuntu',
- unless='ls -l')
- self.assertEqual(result, {'name': 'ls /',
- 'result': True,
- 'comment': 'unless execution succeeded',
- 'changes': {}})
-
- def test_docker_run_docked_onlyif(self):
- from salt.states import dockerio
- salt_fixture = {'docker.retcode': MagicMock(return_value=1),
- 'docker.run_all': None}
- with provision_state(dockerio, salt_fixture):
- result = dockerio.run('ls /', 'ubuntu',
- docked_onlyif='ls -l')
- self.assertEqual(result, {'name': 'ls /',
- 'result': True,
- 'comment': 'docked_onlyif execution failed',
- 'changes': {}})
-
- def test_docker_run_docked_unless(self):
- from salt.states import dockerio
- salt_fixture = {'docker.retcode': MagicMock(return_value=0),
- 'docker.run_all': None}
- with provision_state(dockerio, salt_fixture):
- result = dockerio.run('ls /', 'ubuntu',
- docked_unless='ls -l')
- self.assertEqual(result, {'name': 'ls /',
- 'result': True,
- 'comment': ('docked_unless execution'
- ' succeeded'),
- 'changes': {}})
-
-
-if __name__ == '__main__':
- from integration import run_tests
- run_tests(DockerStateTestCase, needs_daemon=False)
diff --git a/tests/unit/states/dockerio_test.py b/tests/unit/states/dockerio_test.py
new file mode 100644
index 0000000..54f51be
--- /dev/null
+++ b/tests/unit/states/dockerio_test.py
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+
+# Import Python libs
+from __future__ import absolute_import
+from contextlib import contextmanager
+
+# Import Salt Testing libs
+from salttesting import skipIf, TestCase
+from salttesting.mock import NO_MOCK, NO_MOCK_REASON, MagicMock
+
+
+@contextmanager
+def provision_state(module, fixture):
+ previous_dict = getattr(module, '__salt__', {}).copy()
+ try:
+ module.__dict__.setdefault('__salt__', {}).update(fixture)
+ yield
+ finally:
+ setattr(module, '__salt__', previous_dict)
+
+
+@skipIf(NO_MOCK, NO_MOCK_REASON)
+@skipIf(True, 'Skipped: This module has been deprecated.')
+class DockerStateTestCase(TestCase):
+ def test_docker_run_success(self):
+ from salt.states import dockerio
+ salt_fixture = {'docker.retcode': MagicMock(return_value=0),
+ 'docker.run_all': MagicMock(
+ return_value={'stdout': '.\n..\n',
+ 'stderr': '',
+ 'status': True,
+ 'comment': 'Success',
+ 'retcode': 0})}
+
+ with provision_state(dockerio, salt_fixture):
+ result = dockerio.run('ls /', 'ubuntu')
+
+ self.assertEqual(result, {'name': 'ls /',
+ 'result': True,
+ 'comment': 'Success',
+ 'changes': {}})
+
+ def test_docker_run_failure(self):
+ from salt.states import dockerio
+ salt_fixture = {'docker.retcode': MagicMock(return_value=0),
+ 'docker.run_all': MagicMock(
+ return_value={'stdout': '',
+ 'stderr': 'Error',
+ 'status': False,
+ 'comment': 'Failure',
+ 'retcode': 1})}
+
+ with provision_state(dockerio, salt_fixture):
+ result = dockerio.run('ls /', 'ubuntu')
+
+ self.assertEqual(result, {'name': 'ls /',
+ 'result': False,
+ 'comment': 'Failure',
+ 'changes': {}})
+
+ def test_docker_run_onlyif(self):
+ from salt.states import dockerio
+ salt_fixture = {'docker.retcode': MagicMock(return_value=1),
+ 'docker.run_all': None}
+ with provision_state(dockerio, salt_fixture):
+ result = dockerio.run('ls /', 'ubuntu',
+ onlyif='ls -l')
+ self.assertEqual(result, {'name': 'ls /',
+ 'result': True,
+ 'comment': 'onlyif execution failed',
+ 'changes': {}})
+
+ def test_docker_run_unless(self):
+ from salt.states import dockerio
+ salt_fixture = {'docker.retcode': MagicMock(return_value=0),
+ 'docker.run_all': None}
+ with provision_state(dockerio, salt_fixture):
+ result = dockerio.run('ls /', 'ubuntu',
+ unless='ls -l')
+ self.assertEqual(result, {'name': 'ls /',
+ 'result': True,
+ 'comment': 'unless execution succeeded',
+ 'changes': {}})
+
+ def test_docker_run_docked_onlyif(self):
+ from salt.states import dockerio
+ salt_fixture = {'docker.retcode': MagicMock(return_value=1),
+ 'docker.run_all': None}
+ with provision_state(dockerio, salt_fixture):
+ result = dockerio.run('ls /', 'ubuntu',
+ docked_onlyif='ls -l')
+ self.assertEqual(result, {'name': 'ls /',
+ 'result': True,
+ 'comment': 'docked_onlyif execution failed',
+ 'changes': {}})
+
+ def test_docker_run_docked_unless(self):
+ from salt.states import dockerio
+ salt_fixture = {'docker.retcode': MagicMock(return_value=0),
+ 'docker.run_all': None}
+ with provision_state(dockerio, salt_fixture):
+ result = dockerio.run('ls /', 'ubuntu',
+ docked_unless='ls -l')
+ self.assertEqual(result, {'name': 'ls /',
+ 'result': True,
+ 'comment': ('docked_unless execution'
+ ' succeeded'),
+ 'changes': {}})
+
+
+if __name__ == '__main__':
+ from integration import run_tests
+ run_tests(DockerStateTestCase, needs_daemon=False)
diff --git a/tests/unit/utils/network.py b/tests/unit/utils/network.py
index 89db848..72ca857 100644
--- a/tests/unit/utils/network.py
+++ b/tests/unit/utils/network.py
@@ -151,15 +151,16 @@ class NetworkTestCase(TestCase):
self.assertEqual(interfaces,
{'ilbext0': {'inet': [{'address': '10.10.11.11',
'broadcast': '10.10.11.31',
+ 'netmask': '255.255.255.224'},
+ {'address': '10.10.11.12',
+ 'broadcast': '10.10.11.31',
'netmask': '255.255.255.224'}],
- 'inet6': [{'address': '::',
- 'prefixlen': '0'}],
+ 'inet6': [],
'up': True},
'ilbint0': {'inet': [{'address': '10.6.0.11',
'broadcast': '10.6.0.255',
'netmask': '255.255.255.0'}],
- 'inet6': [{'address': '::',
- 'prefixlen': '0'}],
+ 'inet6': [],
'up': True},
'lo0': {'inet': [{'address': '127.0.0.1',
'netmask': '255.0.0.0'}],
@@ -174,8 +175,7 @@ class NetworkTestCase(TestCase):
'up': True},
'vpn0': {'inet': [{'address': '10.6.0.14',
'netmask': '255.0.0.0'}],
- 'inet6': [{'address': '::',
- 'prefixlen': '0'}],
+ 'inet6': [],
'up': True}}
)
diff --git a/tests/unit/utils/utils_test.py b/tests/unit/utils/utils_test.py
index 261af69..11f0baf 100644
--- a/tests/unit/utils/utils_test.py
+++ b/tests/unit/utils/utils_test.py
@@ -527,14 +527,9 @@ class UtilsTestCase(TestCase):
ret = utils.date_cast('Mon Dec 23 10:19:15 MST 2013')
expected_ret = datetime.datetime(2013, 12, 23, 10, 19, 15)
self.assertEqual(ret, expected_ret)
- except ImportError:
- try:
- ret = utils.date_cast('Mon Dec 23 10:19:15 MST 2013')
- expected_ret = datetime.datetime(2013, 12, 23, 10, 19, 15)
- self.assertEqual(ret, expected_ret)
- except RuntimeError:
- # Unparseable without timelib installed
- self.skipTest('\'timelib\' is not installed')
+ except RuntimeError:
+ # Unparseable without timelib installed
+ self.skipTest('\'timelib\' is not installed')
@skipIf(not HAS_TIMELIB, '\'timelib\' is not installed')
def test_date_format(self):
--
2.8.2

View File

@ -0,0 +1,113 @@
From df1f88c51a40e69935830d1664a46dadf514dc69 Mon Sep 17 00:00:00 2001
From: Justin Anderson <janderson@saltstack.com>
Date: Tue, 23 Aug 2016 15:02:31 -0600
Subject: [PATCH 19/19] Fix snapper_test for python26
* Use assertCountEqual instead of assertItemsEqual for Python 3
* Skip one Snapper test on 2.6
There's a slight difference in the diff comparison but we should be
able to catch true failures here with 2.7.
---
tests/unit/modules/snapper_test.py | 41 ++++++++++++++++++++++++++++++--------
1 file changed, 33 insertions(+), 8 deletions(-)
diff --git a/tests/unit/modules/snapper_test.py b/tests/unit/modules/snapper_test.py
index f27b2ba..43f8898 100644
--- a/tests/unit/modules/snapper_test.py
+++ b/tests/unit/modules/snapper_test.py
@@ -6,19 +6,26 @@ Unit tests for the Snapper module
:codeauthor: Pablo Suárez Hernández <psuarezhernandez@suse.de>
'''
+# Import Python libs
from __future__ import absolute_import
+import sys
-from salttesting import TestCase
+# Import Salt Testing libs
+from salttesting import TestCase, skipIf
from salttesting.mock import (
+ NO_MOCK,
+ NO_MOCK_REASON,
MagicMock,
patch,
mock_open,
)
-
-from salt.exceptions import CommandExecutionError
from salttesting.helpers import ensure_in_syspath
+
ensure_in_syspath('../../')
+# Import Salt libs
+import salt.ext.six as six
+from salt.exceptions import CommandExecutionError
from salt.modules import snapper
# Globals
@@ -123,6 +130,13 @@ MODULE_RET = {
"@@ -0,0 +1 @@\n"
"+another foobar",
},
+ '/tmp/foo26': {
+ 'comment': 'text file created',
+ 'diff': "--- /.snapshots/55/snapshot/tmp/foo2 \n"
+ "+++ /tmp/foo2 \n"
+ "@@ -1,0 +1,1 @@\n"
+ "+another foobar",
+ },
'/tmp/foo3': {
'comment': 'binary file changed',
'old_sha256_digest': 'e61f8b762d83f3b4aeb3689564b0ffbe54fa731a69a1e208dc9440ce0f69d19b',
@@ -132,6 +146,7 @@ MODULE_RET = {
}
+@skipIf(NO_MOCK, NO_MOCK_REASON)
class SnapperTestCase(TestCase):
def setUp(self):
self.dbus_mock = MagicMock()
@@ -220,10 +235,16 @@ class SnapperTestCase(TestCase):
@patch('salt.modules.snapper.snapper.GetComparison', MagicMock())
@patch('salt.modules.snapper.snapper.GetFiles', MagicMock(return_value=DBUS_RET['GetFiles']))
def test_status(self):
- self.assertItemsEqual(snapper.status(), MODULE_RET['GETFILES'])
- self.assertItemsEqual(snapper.status(num_pre="42", num_post=43), MODULE_RET['GETFILES'])
- self.assertItemsEqual(snapper.status(num_pre=42), MODULE_RET['GETFILES'])
- self.assertItemsEqual(snapper.status(num_post=43), MODULE_RET['GETFILES'])
+ if six.PY3:
+ self.assertCountEqual(snapper.status(), MODULE_RET['GETFILES'])
+ self.assertCountEqual(snapper.status(num_pre="42", num_post=43), MODULE_RET['GETFILES'])
+ self.assertCountEqual(snapper.status(num_pre=42), MODULE_RET['GETFILES'])
+ self.assertCountEqual(snapper.status(num_post=43), MODULE_RET['GETFILES'])
+ else:
+ self.assertItemsEqual(snapper.status(), MODULE_RET['GETFILES'])
+ self.assertItemsEqual(snapper.status(num_pre="42", num_post=43), MODULE_RET['GETFILES'])
+ self.assertItemsEqual(snapper.status(num_pre=42), MODULE_RET['GETFILES'])
+ self.assertItemsEqual(snapper.status(num_post=43), MODULE_RET['GETFILES'])
@patch('salt.modules.snapper.status', MagicMock(return_value=MODULE_RET['GETFILES']))
def test_changed_files(self):
@@ -268,7 +289,10 @@ class SnapperTestCase(TestCase):
@patch('os.path.isfile', MagicMock(side_effect=[False, True]))
@patch('salt.utils.fopen', mock_open(read_data=FILE_CONTENT["/tmp/foo2"]['post']))
def test_diff_text_file(self):
- self.assertEqual(snapper.diff(), {"/tmp/foo2": MODULE_RET['DIFF']['/tmp/foo2']})
+ if sys.version_info < (2, 7):
+ self.assertEqual(snapper.diff(), {"/tmp/foo2": MODULE_RET['DIFF']['/tmp/foo26']})
+ else:
+ self.assertEqual(snapper.diff(), {"/tmp/foo2": MODULE_RET['DIFF']['/tmp/foo2']})
@patch('salt.modules.snapper._get_num_interval', MagicMock(return_value=(55, 0)))
@patch('salt.modules.snapper.snapper.MountSnapshot', MagicMock(
@@ -278,6 +302,7 @@ class SnapperTestCase(TestCase):
@patch('salt.modules.snapper._is_text_file', MagicMock(return_value=True))
@patch('os.path.isfile', MagicMock(side_effect=[True, True, False, True]))
@patch('os.path.isdir', MagicMock(return_value=False))
+ @skipIf(sys.version_info < (2, 7), 'Python 2.7 required to compare diff properly')
def test_diff_text_files(self):
fopen_effect = [
mock_open(read_data=FILE_CONTENT["/tmp/foo"]['pre']).return_value,
--
2.8.2

View File

@ -0,0 +1,107 @@
From 65dba3e9ab088087943f67367dc27fce00e4cd92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
<psuarezhernandez@suse.com>
Date: Tue, 13 Sep 2016 11:05:35 +0100
Subject: [PATCH 20/20] Integration tests fixes for 2016.3.2
* Fix PillarModuleTest::test_pillar_items: 'info' does not exist in pillar
* Fixing integration tests if azure is not present
* Fixing integration tests failures if 'git' command is missing
Skip git state integration tests if 'git' does not exists
Prevent OSError if 'git' command not found during _git_version()
---
tests/integration/cloud/providers/msazure.py | 17 +++++++++--------
tests/integration/modules/git.py | 15 +++++++++------
tests/integration/modules/pillar.py | 1 -
tests/integration/states/git.py | 2 +-
4 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/tests/integration/cloud/providers/msazure.py b/tests/integration/cloud/providers/msazure.py
index c4934e4..4e53add 100644
--- a/tests/integration/cloud/providers/msazure.py
+++ b/tests/integration/cloud/providers/msazure.py
@@ -53,14 +53,15 @@ def __has_required_azure():
'''
Returns True/False if the required version of the Azure SDK is installed.
'''
- if hasattr(azure, '__version__'):
- version = LooseVersion(azure.__version__)
- else:
- version = LooseVersion(azure.common.__version__)
- if HAS_AZURE is True and REQUIRED_AZURE <= version:
- return True
- else:
- return False
+ if HAS_AZURE:
+ if hasattr(azure, '__version__'):
+ version = LooseVersion(azure.__version__)
+ else:
+ version = LooseVersion(azure.common.__version__)
+
+ if REQUIRED_AZURE <= version:
+ return True
+ return False
@skipIf(HAS_AZURE is False, 'These tests require the Azure Python SDK to be installed.')
diff --git a/tests/integration/modules/git.py b/tests/integration/modules/git.py
index 7c40664..f5c15f3 100644
--- a/tests/integration/modules/git.py
+++ b/tests/integration/modules/git.py
@@ -36,12 +36,15 @@ log = logging.getLogger(__name__)
def _git_version():
- git_version = subprocess.Popen(
- ['git', '--version'],
- shell=False,
- close_fds=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).communicate()[0]
+ try:
+ git_version = subprocess.Popen(
+ ['git', '--version'],
+ shell=False,
+ close_fds=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).communicate()[0]
+ except OSError:
+ return False
if not git_version:
log.debug('Git not installed')
return False
diff --git a/tests/integration/modules/pillar.py b/tests/integration/modules/pillar.py
index b081f76..3d55b4c 100644
--- a/tests/integration/modules/pillar.py
+++ b/tests/integration/modules/pillar.py
@@ -119,7 +119,6 @@ class PillarModuleTest(integration.ModuleCase):
from pillar.items
'''
get_items = self.run_function('pillar.items')
- self.assertDictContainsSubset({'info': 'bar'}, get_items)
self.assertDictContainsSubset({'monty': 'python'}, get_items)
self.assertDictContainsSubset(
{'knights': ['Lancelot', 'Galahad', 'Bedevere', 'Robin']},
diff --git a/tests/integration/states/git.py b/tests/integration/states/git.py
index a78b271..87681ba 100644
--- a/tests/integration/states/git.py
+++ b/tests/integration/states/git.py
@@ -20,6 +20,7 @@ import integration
import salt.utils
+@skip_if_binaries_missing('git')
class GitTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
'''
Validate the git state
@@ -254,7 +255,6 @@ class GitTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
finally:
shutil.rmtree(name, ignore_errors=True)
- @skip_if_binaries_missing('git')
def test_config_set_value_with_space_character(self):
'''
git.config
--
2.8.2

3
html.tar.bz2 Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0899b89ef230b42097f7c147a9babb30d65eac7968bd05318eac42ec9d8a7ec9
size 5486695

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4a81273ab4b01e0f1d29b28ab99a16eb94e5c430107b05491c94f3baf8b95c99
size 6972776

3
salt-2016.3.2.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6a84b724d02b0dba438dea57650724064675d82620e66749bd2fe8f21da71be0
size 8014793

View File

@ -1,3 +1,178 @@
-------------------------------------------------------------------
Tue Sep 27 23:55:03 UTC 2016 - mrueckert@suse.de
- splitting out the susemanager integration plugins into their own
subpackages. ATM this only contains the zypp plugin to tell
susemanager about manually installed packages.
-------------------------------------------------------------------
Tue Sep 13 15:07:44 UTC 2016 - pablo.suarezhernandez@suse.com
- Unit and integration tests fixes for 2016.3.2
Add:
* 0018-Unit-tests-fixes-for-2016.3.2.patch
* 0019-Fix-snapper_test-for-python26.patch
* 0020-Integration-tests-fixes-for-2016.3.2.patch
-------------------------------------------------------------------
Fri Sep 2 09:50:57 UTC 2016 - pablo.suarezhernandez@suse.com
- Prevent pkg.install failure for expired keys (bsc#996455)
Add:
* 0017-Check-for-single-quote-before-splitting-on-single-qu.patch
-------------------------------------------------------------------
Tue Aug 30 12:24:45 UTC 2016 - bmaryniuk@suse.com
- Required D-Bus and generating machine ID where it is missing
-------------------------------------------------------------------
Fri Aug 26 13:11:58 UTC 2016 - bmaryniuk@suse.com
- Fix sphinx crashes when documentation is being generated
Add script for documentation update.
Add:
* 0016-Improve-Mock-to-be-flexible-and-able-to-mock-methods.patch
* update-documentation.sh
-------------------------------------------------------------------
Tue Aug 16 12:01:59 UTC 2016 - bmaryniuk@suse.com
- Fix pkg.installed refresh repo failure (bsc#993549)
Fix salt.states.pkgrepo.management no change failure (bsc#990440)
Add:
* 0014-Add-ignore_repo_failure-option-to-suppress-zypper-s-.patch
* 0015-Remove-zypper-s-raise-exception-if-mod_repo-has-no-a.patch
-------------------------------------------------------------------
Tue Aug 9 13:40:37 UTC 2016 - bmaryniuk@suse.com
- Deprecate status.uptime one version later
Add:
* 0013-Deprecate-status.uptime-one-version-later.patch
-------------------------------------------------------------------
Mon Aug 8 16:25:04 UTC 2016 - pablo.suarezhernandez@suse.com
- Fix for 0008-checksum-validation-when-zypper-pkg.download.patch
after upstream merging conflict. Prevent zypper test failure.
Update:
* 0008-checksum-validation-when-zypper-pkg.download.patch
-------------------------------------------------------------------
Thu Aug 4 14:56:42 UTC 2016 - mihai.dinca@suse.com
- Update to v2016.3.2
see https://docs.saltstack.com/en/latest/topics/releases/2016.3.2.html
- Removed Patches, applied upstream
* 0010-Getting-the-os-grain-from-CPE_NAME-inside-etc-os-rel.patch
* 0011-snapper-execution-module.patch
* 0012-Force-minion-exit-on-mis-configuration-read.patch
* 0013-fix-salt-summary-to-count-not-responding-minions-cor.patch
* 0014-Move-log-message-from-INFO-to-DEBUG.patch
* 0016-Run-salt-api-as-user-salt-bsc-990029.patch
* 0017-fix-beacon-list-to-include-all-beacons-being-process.patch
- Added Patches back
* 0010-snapper-execution-module.patch
* 0011-fix-salt-summary-to-count-not-responding-minions-cor.patch
* 0012-Run-salt-api-as-user-salt-bsc-990029.patch
-------------------------------------------------------------------
Wed Aug 3 14:50:35 UTC 2016 - pablo.suarezhernandez@suse.com
- Fix beacon list to include all beacons being process
Add:
* 0017-fix-beacon-list-to-include-all-beacons-being-process.patch
-------------------------------------------------------------------
Fri Jul 29 11:48:37 UTC 2016 - kkaempf@suse.com
- Redo patches, sync with github.com/openSUSE/salt
- Renamed patches
* 0016-Getting-the-os-grain-from-CPE_NAME-inside-etc-os-rel.patch
-> 0010-Getting-the-os-grain-from-CPE_NAME-inside-etc-os-rel.patch
* 0017-snapper-execution-module.patch
-> 0011-snapper-execution-module.patch
* 0018-Force-minion-exit-on-mis-configuration-read.patch
-> 0012-Force-minion-exit-on-mis-configuration-read.patch
- Added back (fix upstream merge problems):
* 0008-checksum-validation-when-zypper-pkg.download.patch
* 0009-unit-tests-for-rpm.checksum-and-zypper.download.patch
- fix salt --summary to count not responding minions correctly
(bsc#972311)
* 0013-fix-salt-summary-to-count-not-responding-minions-cor.patch
- Move log message from INFO to DEBUG (bsc#985661)
* 0014-Move-log-message-from-INFO-to-DEBUG.patch
- pkg.list_products on "registerrelease" and "productline"
returns boolean.False if empty (bsc#989193)
* 0015-Bugfix-return-boolean-only-for-isbase-and-installed-.patch
- Run salt-api as user salt like the master (bsc#990029)
* 0016-Run-salt-api-as-user-salt-bsc-990029.patch
-------------------------------------------------------------------
Fri Jul 22 15:16:16 UTC 2016 - darin@darins.net
- Update to v2016.3.1
see https://docs.saltstack.com/en/latest/topics/releases/2016.3.1.html
- Removed Patches, applied upstream
* 0008-Prevent-several-minion-processes-on-the-same-machine.patch
* 0009-checksum-validation-when-zypper-pkg.download.patch
* 0010-unit-tests-for-rpm.checksum-and-zypper.download.patch
* 0011-jobs.exit_success-allow-to-check-if-a-job-has-execut.patch
* 0012-Fix-pkgrepo.managed-gpgkey-argument-bsc-979448.patch
* 0013-fix-groupadd-module-for-sles11-systems.patch
* 0014-Fix-crashing-Maintenence-process.patch
* 0015-Insert-no-refresh-before-install-in-Zypper.patch
-------------------------------------------------------------------
Tue Jul 19 15:03:10 UTC 2016 - bmaryniuk@suse.com
- Bugfix: Exit on configuration read (bsc#985667)
Add:
* 0018-Force-minion-exit-on-mis-configuration-read.patch
-------------------------------------------------------------------
Mon Jul 18 08:32:04 UTC 2016 - pablo.suarezhernandez@suse.com
- Backport: Snapper module for Salt.
Add:
* 0017-snapper-execution-module.patch
-------------------------------------------------------------------
Wed Jun 22 07:56:44 UTC 2016 - pablo.suarezhernandez@suse.com
- Bugfix: Fixed behavior for SUSE OS grains (bsc#970669)
Bugfix: Salt os_family does not detect SLES for SAP (bsc#983017)
Add:
* 0016-Getting-the-os-grain-from-CPE_NAME-inside-etc-os-rel.patch
-------------------------------------------------------------------
Mon Jun 20 11:26:29 UTC 2016 - thipp@suse.com
- Insert --no-refresh before install in Zypper
Add:
* 0015-Insert-no-refresh-before-install-in-Zypper.patch
-------------------------------------------------------------------
Wed Jun 15 11:38:26 UTC 2016 - kkaempf@suse.com
- Update to v2016.3.0
see https://docs.saltstack.com/en/latest/topics/releases/2016.3.0.html
* backwards-incompatible changes:
- The default path for the extension_modules master config option
has been changed.
- add 0014-Fix-crashing-Maintenence-process.patch
see release notes
-------------------------------------------------------------------
Wed Jun 1 09:52:40 UTC 2016 - mihai.dinca@suse.com

170
salt.spec
View File

@ -34,45 +34,80 @@
%bcond_with test
%bcond_with raet
%bcond_without docs
%bcond_with builddocs
Name: salt
Version: 2015.8.10
Version: 2016.3.2
Release: 0
Summary: A parallel remote execution system
License: Apache-2.0
Group: System/Monitoring
Url: http://saltstack.org/
# Git: https://github.com/openSUSE/salt.git
Source0: https://pypi.io/packages/source/s/%{name}/%{name}-%{version}.tar.gz
Source0: https://github.com/saltstack/salt/releases/download/v%{version}/%{name}-%{version}.tar.gz
Source1: README.SUSE
Source2: salt-tmpfiles.d
Source3: html.tar.bz2
# 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: 0001-tserong-suse.com-We-don-t-have-python-systemd-so-not.patch
# 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: 0002-Run-salt-master-as-dedicated-salt-user.patch
# 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: 0003-Check-if-byte-strings-are-properly-encoded-in-UTF-8.patch
# PATCH-FIX-OPENSUSE prevent rebuilds in OBS
# We do not upstream this patch because the issue is on our side
Patch4: 0004-do-not-generate-a-date-in-a-comment-to-prevent-rebui.patch
# PATCH-FIX-OPENSUSE - Upstream default hash type is set to MD5, while we require SHA256 (bsc#955373)
# PR https://github.com/saltstack/salt/pull/35341 (15.08.2016 - not merged yet)
Patch5: 0005-Use-SHA256-hash-type-by-default.patch
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/31798
# PR already merged. This will be gone in the next version
Patch6: 0006-Create-salt-proxy-instantiated-service-file.patch
# 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)
Patch7: 0007-Add-SUSE-Manager-plugin.patch
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/33464
Patch8: 0008-Prevent-several-minion-processes-on-the-same-machine.patch
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/33469
Patch9: 0009-checksum-validation-when-zypper-pkg.download.patch
# PR already merged. This will be gone in the next version
Patch8: 0008-checksum-validation-when-zypper-pkg.download.patch
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/33501
Patch10: 0010-unit-tests-for-rpm.checksum-and-zypper.download.patch
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/33465
Patch11: 0011-jobs.exit_success-allow-to-check-if-a-job-has-execut.patch
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/33432
# https://github.com/saltstack/salt/pull/33581
Patch12: 0012-Fix-pkgrepo.managed-gpgkey-argument-bsc-979448.patch
# PR already merged. This will be gone in the next version
Patch9: 0009-unit-tests-for-rpm.checksum-and-zypper.download.patch
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/34599 (backport from dev)
# PR already merged. This will be gone in the next version
Patch10: 0010-snapper-execution-module.patch
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/34165
Patch11: 0011-fix-salt-summary-to-count-not-responding-minions-cor.patch
# PATCH-FIX-OPENSUSE
# We do not upstream this patch because this is suse custom configuration
Patch12: 0012-Run-salt-api-as-user-salt-bsc-990029.patch
# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/35196
# PR already merged. This will be gone in the next version
Patch13: 0013-Deprecate-status.uptime-one-version-later.patch
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/35448
Patch14: 0014-Add-ignore_repo_failure-option-to-suppress-zypper-s-.patch
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/35451
Patch15: 0015-Remove-zypper-s-raise-exception-if-mod_repo-has-no-a.patch
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/35763
Patch16: 0016-Improve-Mock-to-be-flexible-and-able-to-mock-methods.patch
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/36000
Patch17: 0017-Check-for-single-quote-before-splitting-on-single-qu.patch
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/36139
# https://github.com/saltstack/salt/pull/36158
# https://github.com/saltstack/salt/pull/36227
Patch18: 0018-Unit-tests-fixes-for-2016.3.2.patch
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/35715
# https://github.com/saltstack/salt/pull/35983
# https://github.com/saltstack/salt/pull/34826
Patch19: 0019-Fix-snapper_test-for-python26.patch
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/36263
Patch20: 0020-Integration-tests-fixes-for-2016.3.2.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: logrotate
@ -111,17 +146,27 @@ BuildRequires: python-salt-testing >= 2015.2.16
BuildRequires: python-unittest2
BuildRequires: python-xml
%endif
%if %{with docs}
#for docs
%if %{with builddocs}
BuildRequires: python-sphinx
%endif
%if 0%{?suse_version} > 1010
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: python
#
@ -414,6 +459,20 @@ Zsh command line completion support for %{name}.
%endif
%if 0%{?suse_version}
%package susemanager
Summary: SUSE Manager Integration
Group: System/Management
Requires: %{name} = %{version}-%{release}
%if 0%{?suse_version} > 1110
BuildArch: noarch
%endif
%description susemanager
SUSE Manager Integration for various tools on the system.
%endif
%prep
%setup -q -n salt-%{version}
cp %{S:1} .
@ -427,18 +486,33 @@ cp %{S:1} .
# This is SUSE-only patch
%if 0%{?suse_version}
%patch7 -p1
%patch8 -p1
%endif
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%build
python setup.py --salt-transport=both build
%if %{with docs}
%if %{with docs} && %{without builddocs}
# extract docs from the tarball
mkdir -p doc/_build
pushd doc/_build/
tar xfv %{S:3}
popd
%endif
%if %{with docs} && %{with builddocs}
## documentation
cd doc && make html && rm _build/html/.buildinfo && rm _build/html/_images/proxy_minions.png && cd _build/html && chmod -R -x+X *
%endif
@ -546,6 +620,11 @@ install -Dpm 0644 pkg/fish-completions/* %{buildroot}%{fish_completions_dir}
echo "transport: raet" > %{buildroot}%{_sysconfdir}/salt/master.d/transport-raet.conf
echo "transport: raet" > %{buildroot}%{_sysconfdir}/salt/minion.d/transport-raet.conf
%if 0%{?suse_version} > 1020
%fdupes %{buildroot}%{_docdir}
%fdupes %{buildroot}%{python_sitelib}
%endif
%check
%if %{with test}
python setup.py test --runtests-opts=-u
@ -555,9 +634,50 @@ python setup.py test --runtests-opts=-u
getent group salt >/dev/null || %{_sbindir}/groupadd -r salt
getent passwd salt >/dev/null || %{_sbindir}/useradd -r -g salt -d /srv/salt -s /bin/false -c "salt-master daemon" salt
%if %{with systemd}
%post
%if %{with systemd}
systemd-tmpfiles --create /usr/lib/tmpfiles.d/salt.conf || true
%else
dbus-uuidgen --ensure
%endif
%preun proxy
%if %{with systemd}
%service_del_preun salt-proxy@.service
%else
%if 0%{?suse_version}
%stop_on_removal salt-proxy
%else
if [ $1 -eq 0 ] ; then
/sbin/service salt-proxy stop >/dev/null 2>&1
/sbin/chkconfig --del salt-proxy
fi
%endif
%endif
%pre proxy
%if %{with systemd}
%service_add_pre salt-proxy@.service
%endif
%post proxy
%if %{with systemd}
%service_add_post salt-proxy@.service
%fillup_only
%else
%if 0%{?suse_version}
%fillup_and_insserv
%endif
%endif
%postun proxy
%if %{with systemd}
%service_del_postun salt-proxy@.service
%else
%if 0%{?suse_version}
%insserv_cleanup
%restart_on_update salt-proxy
%endif
%endif
%preun syndic
@ -781,13 +901,9 @@ fi
%dir %attr(0750, root, root) %{_sysconfdir}/salt/minion.d/
%dir %attr(0750, root, root) %{_sysconfdir}/salt/pki/minion/
%dir %attr(0750, root, root) %{_localstatedir}/cache/salt/minion/
#%dir %ghost %attr(0750, root, salt) %{_localstatedir}/run/salt/minion
%{_sbindir}/rcsalt-minion
# Install plugin only on SUSE machines
%if 0%{?suse_version}
%{_prefix}/lib/zypp/plugins/commit/susemanager
%endif
%if %{with systemd}
%{_unitdir}/salt-minion.service
%else
@ -840,6 +956,7 @@ fi
%dir %attr(0750, salt, salt) %{_localstatedir}/cache/salt/master/roots/
%dir %attr(0750, salt, salt) %{_localstatedir}/cache/salt/master/syndics/
%dir %attr(0750, salt, salt) %{_localstatedir}/cache/salt/master/tokens/
#%dir %ghost %attr(0750, salt, salt) %{_localstatedir}/run/salt/master/
%files raet
%defattr(-,root,root,-)
@ -853,6 +970,7 @@ fi
%{_bindir}/salt-unity
%{_mandir}/man1/salt-unity.1.gz
%{_mandir}/man1/salt-call.1.gz
%{_mandir}/man1/spm.1.gz
%config(noreplace) %{_sysconfdir}/logrotate.d/salt
%{python_sitelib}/*
%exclude %{python_sitelib}/salt/cloud/deploy/*.sh
@ -863,6 +981,7 @@ fi
%dir %attr(0750, root, salt) %{_sysconfdir}/salt/pki
%dir %attr(0750, salt, salt) %{_localstatedir}/log/salt
%dir %attr(0750, root, salt) %{_localstatedir}/cache/salt
#%dir %ghost %attr(0750, root, salt) %{_localstatedir}/run/salt
%dir %attr(0750, root, salt) /srv/spm
%if %{with systemd}
/usr/lib/tmpfiles.d/salt.conf
@ -896,4 +1015,11 @@ fi
%dir %{fish_dir}
%endif
# Install plugin only on SUSE machines
%if 0%{?suse_version}
%files susemanager
%defattr(-,root,root)
%{_prefix}/lib/zypp/plugins/commit/susemanager
%endif
%changelog

64
update-documentation.sh Normal file
View File

@ -0,0 +1,64 @@
#!/bin/bash
#
# Update html.tar.bz2 documentation tarball
# Author: Bo Maryniuk <bo@suse.de>
#
function check_env() {
for cmd in "sphinx-build" "make" "quilt"; do
if [ -z "$(which $cmd 2>/dev/null)" ]; then
echo "Error: '$cmd' is missing."
exit 1;
fi
done
}
function quilt_setup() {
quilt setup salt.spec
cd $1
quilt push -a
}
function build_docs() {
cd $1
make html
rm _build/html/.buildinfo
cd _build/html
chmod -R -x+X *
cd ..
tar cvf - html | bzip2 > /tmp/html.tar.bz2
}
function write_changelog() {
mv salt.changes salt.changes.previous
TIME=$(date -u +'%a %b %d %T %Z %Y')
MAIL=$1
SEP="-------------------------------------------------------------------"
cat <<EOF > salt.changes
$SEP
$TIME - $MAIL
- Updated html.tar.bz2 documentation tarball.
EOF
cat salt.changes.previous >> salt.changes
rm salt.changes.previous
}
if [ -z "$1" ]; then
echo "Usage: $0 <your e-mail>"
exit 1;
fi
check_env;
START=$(pwd)
SRC_DIR="salt-$(cat salt.spec | grep ^Version: | cut -d: -f2 | sed -e 's/[[:blank:]]//g')";
quilt_setup $SRC_DIR
build_docs doc
cd $START
rm -rf $SRC_DIR
mv /tmp/html.tar.bz2 $START
echo "Done"
echo "---------------"