mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
Merge pull request #41856 from meaksh/2017.7-suse-leftovers-part-two
SUSE leftovers for 2017.7.0 RC
This commit is contained in:
commit
278b5614d0
1230
conf/suse/master
Normal file
1230
conf/suse/master
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,11 @@
|
||||
[Unit]
|
||||
Description=The Salt API
|
||||
Documentation=man:salt-api(1) file:///usr/share/doc/salt/html/contents.html https://docs.saltstack.com/en/latest/contents.html
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=salt
|
||||
Type=simple
|
||||
Environment=SHELL=/bin/bash
|
||||
LimitNOFILE=8192
|
||||
ExecStart=/usr/bin/salt-api
|
||||
TimeoutStopSec=3
|
||||
|
25
pkg/suse/salt-common.logrotate
Normal file
25
pkg/suse/salt-common.logrotate
Normal file
@ -0,0 +1,25 @@
|
||||
/var/log/salt/master {
|
||||
su salt salt
|
||||
weekly
|
||||
missingok
|
||||
rotate 7
|
||||
compress
|
||||
notifempty
|
||||
}
|
||||
|
||||
/var/log/salt/minion {
|
||||
weekly
|
||||
missingok
|
||||
rotate 7
|
||||
compress
|
||||
notifempty
|
||||
}
|
||||
|
||||
/var/log/salt/key {
|
||||
su salt salt
|
||||
weekly
|
||||
missingok
|
||||
rotate 7
|
||||
compress
|
||||
notifempty
|
||||
}
|
13
pkg/suse/salt-master.service
Normal file
13
pkg/suse/salt-master.service
Normal file
@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=The Salt Master Server
|
||||
Documentation=man:salt-master(1) file:///usr/share/doc/salt/html/contents.html https://docs.saltstack.com/en/latest/contents.html
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
LimitNOFILE=16384
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/salt-master
|
||||
TasksMax=infinity
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
23
pkg/suse/salt-minion
Normal file → Executable file
23
pkg/suse/salt-minion
Normal file → Executable file
@ -51,8 +51,23 @@ SERVICE=salt-minion
|
||||
PROCESS=salt-minion
|
||||
|
||||
RETVAL=0
|
||||
WATCHDOG_CRON="/etc/cron.d/salt-minion"
|
||||
|
||||
set_watchdog() {
|
||||
if [ ! -f $WATCHDOG_CRON ]; then
|
||||
echo -e '* * * * * root /usr/bin/salt-daemon-watcher --with-init\n' > $WATCHDOG_CRON
|
||||
# Kick the watcher for 1 minute immediately, because cron will wake up only afterwards
|
||||
/usr/bin/salt-daemon-watcher --with-init & disown
|
||||
fi
|
||||
}
|
||||
|
||||
remove_watchdog() {
|
||||
rm $WATCHDOG_CRON 2>/dev/null || true
|
||||
kill -9 $(ps uax | grep [s]alt-daemon-watcher | awk '{print $2}') 2>/dev/null
|
||||
}
|
||||
|
||||
start() {
|
||||
set_watchdog;
|
||||
echo -n $"Starting salt-minion daemon: "
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
startproc -p /var/run/$SERVICE.pid $SALTMINION -d $MINION_ARGS
|
||||
@ -80,6 +95,10 @@ start() {
|
||||
}
|
||||
|
||||
stop() {
|
||||
IS_RESTARTING=$1
|
||||
if [ -z $IS_RESTARTING ]; then
|
||||
remove_watchdog;
|
||||
fi
|
||||
echo -n $"Stopping salt-minion daemon: "
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
killproc -TERM $SALTMINION
|
||||
@ -101,8 +120,8 @@ stop() {
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
stop 1;
|
||||
start;
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
|
14
pkg/suse/salt-minion.service.rhel7
Normal file
14
pkg/suse/salt-minion.service.rhel7
Normal file
@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=The Salt Minion
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
LimitNOFILE=8192
|
||||
ExecStart=/usr/bin/salt-minion
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
RestartSec=15
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -427,16 +427,30 @@ def _run(name, **kwargs):
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
if aspec.varargs and aspec.varargs in kwargs:
|
||||
varargs = kwargs.pop(aspec.varargs)
|
||||
if aspec.varargs:
|
||||
if aspec.varargs == 'name':
|
||||
rarg = 'm_name'
|
||||
elif aspec.varargs == 'fun':
|
||||
rarg = 'm_fun'
|
||||
elif aspec.varargs == 'names':
|
||||
rarg = 'm_names'
|
||||
elif aspec.varargs == 'state':
|
||||
rarg = 'm_state'
|
||||
elif aspec.varargs == 'saltenv':
|
||||
rarg = 'm_saltenv'
|
||||
else:
|
||||
rarg = aspec.varargs
|
||||
|
||||
if not isinstance(varargs, list):
|
||||
msg = "'{0}' must be a list."
|
||||
ret['comment'] = msg.format(aspec.varargs)
|
||||
ret['result'] = False
|
||||
return ret
|
||||
if rarg in kwargs:
|
||||
varargs = kwargs.pop(rarg)
|
||||
|
||||
args.extend(varargs)
|
||||
if not isinstance(varargs, list):
|
||||
msg = "'{0}' must be a list."
|
||||
ret['comment'] = msg.format(aspec.varargs)
|
||||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
args.extend(varargs)
|
||||
|
||||
nkwargs = {}
|
||||
if aspec.keywords and aspec.keywords in kwargs:
|
||||
|
@ -1877,7 +1877,7 @@ def downloaded(name,
|
||||
ignore_epoch=None,
|
||||
**kwargs):
|
||||
'''
|
||||
.. versionadded:: Oxygen
|
||||
.. versionadded:: 2017.7.0
|
||||
|
||||
Ensure that the package is downloaded, and that it is the correct version
|
||||
(if specified).
|
||||
@ -2014,7 +2014,7 @@ def downloaded(name,
|
||||
|
||||
def patch_installed(name, advisory_ids=None, downloadonly=None, **kwargs):
|
||||
'''
|
||||
.. versionadded:: Oxygen
|
||||
.. versionadded:: 2017.7.0
|
||||
|
||||
Ensure that packages related to certain advisory ids are installed.
|
||||
|
||||
@ -2094,7 +2094,7 @@ def patch_installed(name, advisory_ids=None, downloadonly=None, **kwargs):
|
||||
|
||||
def patch_downloaded(name, advisory_ids=None, **kwargs):
|
||||
'''
|
||||
.. versionadded:: Oxygen
|
||||
.. versionadded:: 2017.7.0
|
||||
|
||||
Ensure that packages related to certain advisory ids are downloaded.
|
||||
|
||||
|
26
scripts/suse/watchdog/salt-daemon-watcher
Executable file
26
scripts/suse/watchdog/salt-daemon-watcher
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Author: Bo Maryniuk <bo@suse.de>
|
||||
# Requires: yum install propcps
|
||||
#
|
||||
# Runs every minute from crontab,
|
||||
# checks salt-minion every 10 seconds.
|
||||
#
|
||||
# Use this with a following crontab:
|
||||
# * * * * * /path/to/this/script
|
||||
|
||||
if [ "$1" != "--with-init" ]; then
|
||||
echo "This command is not used directly."
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
SHELL=/bin/sh
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
|
||||
for iter in {1..5}; do
|
||||
if [[ $(pgrep salt-minion) == "" ]]; then
|
||||
service salt-minion restart
|
||||
fi
|
||||
sleep 10;
|
||||
done
|
||||
true
|
20
scripts/suse/yum/plugins/README.md
Normal file
20
scripts/suse/yum/plugins/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
## What it is
|
||||
|
||||
Plugin which provides a notification mechanism to Salt, if Yum is
|
||||
used outside of it.
|
||||
|
||||
## Installation
|
||||
|
||||
Configuration files are going to:
|
||||
|
||||
`/etc/yum/pluginconf.d/[name].conf`
|
||||
|
||||
Plugin itself goes to:
|
||||
|
||||
`/usr/share/yum-plugins/[name].conf`
|
||||
|
||||
## Permissions
|
||||
|
||||
User: root
|
||||
Group: root
|
||||
Mode: 644
|
2
scripts/suse/yum/plugins/yumnotify.conf
Normal file
2
scripts/suse/yum/plugins/yumnotify.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
enabled=1
|
55
scripts/suse/yum/plugins/yumnotify.py
Normal file
55
scripts/suse/yum/plugins/yumnotify.py
Normal file
@ -0,0 +1,55 @@
|
||||
# Copyright (c) 2016 SUSE Linux LLC
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Author: Bo Maryniuk <bo@suse.de>
|
||||
|
||||
from yum.plugins import TYPE_CORE
|
||||
from yum import config
|
||||
import os
|
||||
import hashlib
|
||||
|
||||
CK_PATH = "/var/cache/salt/minion/rpmdb.cookie"
|
||||
RPM_PATH = "/var/lib/rpm/Packages"
|
||||
|
||||
requires_api_version = '2.5'
|
||||
plugin_type = TYPE_CORE
|
||||
|
||||
|
||||
def _get_mtime():
|
||||
"""
|
||||
Get the modified time of the RPM Database.
|
||||
|
||||
Returns:
|
||||
Unix ticks
|
||||
"""
|
||||
return os.path.exists(RPM_PATH) and int(os.path.getmtime(RPM_PATH)) or 0
|
||||
|
||||
|
||||
def _get_checksum():
|
||||
"""
|
||||
Get the checksum of the RPM Database.
|
||||
|
||||
Returns:
|
||||
hexdigest
|
||||
"""
|
||||
digest = hashlib.md5()
|
||||
with open(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 posttrans_hook(conduit):
|
||||
"""
|
||||
Hook after the package installation transaction.
|
||||
|
||||
:param conduit:
|
||||
:return:
|
||||
"""
|
||||
# Integrate Yum with Salt
|
||||
if 'SALT_RUNNING' not in os.environ:
|
||||
with open(CK_PATH, 'w') as ck_fh:
|
||||
ck_fh.write('{chksum} {mtime}\n'.format(chksum=_get_checksum(), mtime=_get_mtime()))
|
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()
|
@ -73,9 +73,15 @@ class ModuleStateTest(TestCase, LoaderModuleMockMixin):
|
||||
keywords=None,
|
||||
defaults=False)
|
||||
|
||||
cls.bspec = ArgSpec(args=[],
|
||||
varargs='names',
|
||||
keywords='kwargs',
|
||||
defaults=None)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
del cls.aspec
|
||||
del cls.bspec
|
||||
|
||||
def test_run_module_not_available(self):
|
||||
'''
|
||||
@ -88,6 +94,16 @@ class ModuleStateTest(TestCase, LoaderModuleMockMixin):
|
||||
assert ret['comment'] == "Unavailable function: {0}.".format(CMD)
|
||||
assert not ret['result']
|
||||
|
||||
def test_module_run_hidden_varargs(self):
|
||||
'''
|
||||
Tests the return of module.run state when hidden varargs are used with
|
||||
wrong type.
|
||||
'''
|
||||
with patch('salt.utils.args.get_function_argspec', MagicMock(return_value=self.bspec)):
|
||||
ret = module._run(CMD, m_names='anyname')
|
||||
comment = "'names' must be a list."
|
||||
self.assertEqual(ret['comment'], comment)
|
||||
|
||||
def test_run_testmode(self):
|
||||
'''
|
||||
Tests the return of the module.run state when test=True is passed.
|
||||
|
@ -37,6 +37,7 @@ EXCLUDED_FILES = [
|
||||
'tests/consist.py',
|
||||
'tests/modparser.py',
|
||||
'tests/committer_parser.py',
|
||||
'tests/zypp_plugin.py',
|
||||
'tests/unit/transport/mixins.py',
|
||||
'tests/integration/utils/testprogram.py',
|
||||
]
|
||||
|
45
tests/unit/test_zypp_plugins.py
Normal file
45
tests/unit/test_zypp_plugins.py
Normal file
@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Bo Maryniuk <bo@suse.de>`
|
||||
'''
|
||||
|
||||
# Import Python Libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from tests.support.unit import TestCase, skipIf
|
||||
from tests.support.mock import (
|
||||
MagicMock,
|
||||
patch,
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON
|
||||
)
|
||||
|
||||
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', 'suse', '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('__builtin__.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')
|
65
tests/zypp_plugin.py
Normal file
65
tests/zypp_plugin.py
Normal file
@ -0,0 +1,65 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
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…
Reference in New Issue
Block a user