66ae6bcfbd
Update to 2016.11.2 version, bugfixes OBS-URL: https://build.opensuse.org/request/show/458508 OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=85
223 lines
5.7 KiB
Diff
223 lines
5.7 KiB
Diff
From 2616f36c3a1131a73546449d33d917783f6f1f7b Mon Sep 17 00:00:00 2001
|
|
From: Bo Maryniuk <bo@suse.de>
|
|
Date: Mon, 9 May 2016 10:33:44 +0200
|
|
Subject: [PATCH] Add zypp-notify plugin
|
|
|
|
* Add unit test to the libzypp drift detector plugin
|
|
---
|
|
scripts/zypper/plugins/commit/README.md | 3 ++
|
|
scripts/zypper/plugins/commit/zyppnotify | 59 +++++++++++++++++++++++++++++
|
|
tests/unit/zypp_plugins_test.py | 51 +++++++++++++++++++++++++
|
|
tests/zypp_plugin.py | 64 ++++++++++++++++++++++++++++++++
|
|
4 files changed, 177 insertions(+)
|
|
create mode 100644 scripts/zypper/plugins/commit/README.md
|
|
create mode 100755 scripts/zypper/plugins/commit/zyppnotify
|
|
create mode 100644 tests/unit/zypp_plugins_test.py
|
|
create mode 100644 tests/zypp_plugin.py
|
|
|
|
diff --git a/scripts/zypper/plugins/commit/README.md b/scripts/zypper/plugins/commit/README.md
|
|
new file mode 100644
|
|
index 0000000000..01c8917c8e
|
|
--- /dev/null
|
|
+++ b/scripts/zypper/plugins/commit/README.md
|
|
@@ -0,0 +1,3 @@
|
|
+# Zypper plugins
|
|
+
|
|
+Plugins here are required to interact with SUSE Manager in conjunction of SaltStack and Zypper.
|
|
diff --git a/scripts/zypper/plugins/commit/zyppnotify b/scripts/zypper/plugins/commit/zyppnotify
|
|
new file mode 100755
|
|
index 0000000000..268298b108
|
|
--- /dev/null
|
|
+++ b/scripts/zypper/plugins/commit/zyppnotify
|
|
@@ -0,0 +1,59 @@
|
|
+#!/usr/bin/python
|
|
+#
|
|
+# Copyright (c) 2016 SUSE Linux LLC
|
|
+# All Rights Reserved.
|
|
+#
|
|
+# Author: Bo Maryniuk <bo@suse.de>
|
|
+
|
|
+import sys
|
|
+import os
|
|
+import hashlib
|
|
+
|
|
+from zypp_plugin import Plugin
|
|
+
|
|
+
|
|
+class DriftDetector(Plugin):
|
|
+ """
|
|
+ Return diff of the installed packages outside the Salt.
|
|
+ """
|
|
+ def __init__(self):
|
|
+ Plugin.__init__(self)
|
|
+ self.ck_path = "/var/cache/salt/minion/rpmdb.cookie"
|
|
+ self.rpm_path = "/var/lib/rpm/Packages"
|
|
+
|
|
+ def _get_mtime(self):
|
|
+ '''
|
|
+ Get the modified time of the RPM Database.
|
|
+ Returns:
|
|
+ Unix ticks
|
|
+ '''
|
|
+ return os.path.exists(self.rpm_path) and int(os.path.getmtime(self.rpm_path)) or 0
|
|
+
|
|
+ def _get_checksum(self):
|
|
+ '''
|
|
+ Get the checksum of the RPM Database.
|
|
+ Returns:
|
|
+ hexdigest
|
|
+ '''
|
|
+ digest = hashlib.md5()
|
|
+ with open(self.rpm_path, "rb") as rpm_db_fh:
|
|
+ while True:
|
|
+ buff = rpm_db_fh.read(0x1000)
|
|
+ if not buff:
|
|
+ break
|
|
+ digest.update(buff)
|
|
+
|
|
+ return digest.hexdigest()
|
|
+
|
|
+ def PLUGINEND(self, headers, body):
|
|
+ """
|
|
+ Hook when plugin closes Zypper's transaction.
|
|
+ """
|
|
+ if 'SALT_RUNNING' not in os.environ:
|
|
+ with open(self.ck_path, 'w') as ck_fh:
|
|
+ ck_fh.write('{chksum} {mtime}\n'.format(chksum=self._get_checksum(), mtime=self._get_mtime()))
|
|
+
|
|
+ self.ack()
|
|
+
|
|
+
|
|
+DriftDetector().main()
|
|
diff --git a/tests/unit/zypp_plugins_test.py b/tests/unit/zypp_plugins_test.py
|
|
new file mode 100644
|
|
index 0000000000..550403cc24
|
|
--- /dev/null
|
|
+++ b/tests/unit/zypp_plugins_test.py
|
|
@@ -0,0 +1,51 @@
|
|
+# -*- coding: utf-8 -*-
|
|
+'''
|
|
+ :codeauthor: :email:`Bo Maryniuk <bo@suse.de>`
|
|
+'''
|
|
+
|
|
+# Import Python Libs
|
|
+from __future__ import absolute_import
|
|
+
|
|
+# Import Salt Testing Libs
|
|
+from salttesting.helpers import ensure_in_syspath
|
|
+from salttesting import TestCase, skipIf
|
|
+from salttesting.mock import (
|
|
+ MagicMock,
|
|
+ patch,
|
|
+ NO_MOCK,
|
|
+ NO_MOCK_REASON
|
|
+)
|
|
+
|
|
+ensure_in_syspath('../')
|
|
+
|
|
+import os
|
|
+import imp
|
|
+from zypp_plugin import BogusIO
|
|
+
|
|
+zyppnotify = imp.load_source('zyppnotify', os.path.sep.join(os.path.dirname(__file__).split(
|
|
+ os.path.sep)[:-2] + ['scripts', 'zypper', 'plugins', 'commit', 'zyppnotify']))
|
|
+
|
|
+@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
+class ZyppPluginsTestCase(TestCase):
|
|
+ '''
|
|
+ Test shipped libzypp plugins.
|
|
+ '''
|
|
+ def test_drift_detector(self):
|
|
+ '''
|
|
+ Test drift detector for a correct cookie file.
|
|
+ Returns:
|
|
+
|
|
+ '''
|
|
+ drift = zyppnotify.DriftDetector()
|
|
+ drift._get_mtime = MagicMock(return_value=123)
|
|
+ drift._get_checksum = MagicMock(return_value='deadbeef')
|
|
+ bogus_io = BogusIO()
|
|
+ with patch('zyppnotify.open', bogus_io):
|
|
+ drift.PLUGINEND(None, None)
|
|
+ self.assertEqual(str(bogus_io), 'deadbeef 123\n')
|
|
+ self.assertEqual(bogus_io.mode, 'w')
|
|
+ self.assertEqual(bogus_io.path, '/var/cache/salt/minion/rpmdb.cookie')
|
|
+
|
|
+if __name__ == '__main__':
|
|
+ from integration import run_tests
|
|
+ run_tests(ZyppPluginsTestCase, needs_daemon=False)
|
|
diff --git a/tests/zypp_plugin.py b/tests/zypp_plugin.py
|
|
new file mode 100644
|
|
index 0000000000..218f703811
|
|
--- /dev/null
|
|
+++ b/tests/zypp_plugin.py
|
|
@@ -0,0 +1,64 @@
|
|
+'''
|
|
+Related to zypp_plugins_test.py module.
|
|
+'''
|
|
+
|
|
+
|
|
+class Plugin(object):
|
|
+ '''
|
|
+ Bogus module for Zypp Plugins tests.
|
|
+ '''
|
|
+ def ack(self):
|
|
+ '''
|
|
+ Acknowledge that the plugin had finished the transaction
|
|
+ Returns:
|
|
+
|
|
+ '''
|
|
+
|
|
+ def main(self):
|
|
+ '''
|
|
+ Register plugin
|
|
+ Returns:
|
|
+
|
|
+ '''
|
|
+
|
|
+
|
|
+class BogusIO(object):
|
|
+ '''
|
|
+ Read/write logger.
|
|
+ '''
|
|
+
|
|
+ def __init__(self):
|
|
+ self.content = list()
|
|
+ self.closed = False
|
|
+
|
|
+ def __str__(self):
|
|
+ return '\n'.join(self.content)
|
|
+
|
|
+ def __call__(self, *args, **kwargs):
|
|
+ self.path, self.mode = args
|
|
+ return self
|
|
+
|
|
+ def __exit__(self, exc_type, exc_val, exc_tb):
|
|
+ self.close()
|
|
+
|
|
+ def __enter__(self):
|
|
+ return self
|
|
+
|
|
+ def write(self, data):
|
|
+ '''
|
|
+ Simulate writing data
|
|
+ Args:
|
|
+ data:
|
|
+
|
|
+ Returns:
|
|
+
|
|
+ '''
|
|
+ self.content.append(data)
|
|
+
|
|
+ def close(self):
|
|
+ '''
|
|
+ Simulate closing the IO object.
|
|
+ Returns:
|
|
+
|
|
+ '''
|
|
+ self.closed = True
|
|
--
|
|
2.11.0
|
|
|
|
|