mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 17:50:20 +00:00
Add zypp-notify plugin
* Add unit test to the libzypp drift detector plugin
This commit is contained in:
parent
0cf36b487b
commit
1c817bb6c9
4 changed files with 177 additions and 0 deletions
3
scripts/suse/zypper/plugins/commit/README.md
Normal file
3
scripts/suse/zypper/plugins/commit/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Zypper plugins
|
||||
|
||||
Plugins here are required to interact with SUSE Manager in conjunction of SaltStack and Zypper.
|
59
scripts/suse/zypper/plugins/commit/zyppnotify
Executable file
59
scripts/suse/zypper/plugins/commit/zyppnotify
Executable file
|
@ -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()
|
51
tests/unit/zypp_plugins_test.py
Normal file
51
tests/unit/zypp_plugins_test.py
Normal file
|
@ -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)
|
64
tests/zypp_plugin.py
Normal file
64
tests/zypp_plugin.py
Normal file
|
@ -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
|
Loading…
Add table
Reference in a new issue