mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch 'develop' of https://github.com/saltstack/salt into develop
This commit is contained in:
commit
9fc390ad15
32 changed files with 753 additions and 152 deletions
|
@ -1,4 +1,4 @@
|
|||
.TH "SALT-CALL" "1" "April 27, 2012" "0.9.9" "Salt"
|
||||
.TH "SALT-CALL" "1" "May 11, 2012" "0.9.9" "Salt"
|
||||
.SH NAME
|
||||
salt-call \- salt-call Documentation
|
||||
.
|
||||
|
@ -95,6 +95,11 @@ Print the output from the salt command in json.
|
|||
.B \-\-no\-color
|
||||
Disable all colored output
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch@gmail.com> and many others, please see the Authors file
|
||||
.SH COPYRIGHT
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH "SALT-CP" "1" "April 27, 2012" "0.9.9" "Salt"
|
||||
.TH "SALT-CP" "1" "May 11, 2012" "0.9.9" "Salt"
|
||||
.SH NAME
|
||||
salt-cp \- salt-cp Documentation
|
||||
.
|
||||
|
@ -110,6 +110,11 @@ The location of the salt master configuration file, the salt master
|
|||
settings are required to know where the connections are;
|
||||
default=/etc/salt/master
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch@gmail.com> and many others, please see the Authors file
|
||||
.SH COPYRIGHT
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH "SALT-KEY" "1" "April 27, 2012" "0.9.9" "Salt"
|
||||
.TH "SALT-KEY" "1" "May 11, 2012" "0.9.9" "Salt"
|
||||
.SH NAME
|
||||
salt-key \- salt-key Documentation
|
||||
.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH "SALT-MASTER" "1" "April 27, 2012" "0.9.9" "Salt"
|
||||
.TH "SALT-MASTER" "1" "May 11, 2012" "0.9.9" "Salt"
|
||||
.SH NAME
|
||||
salt-master \- salt-master Documentation
|
||||
.
|
||||
|
@ -71,6 +71,11 @@ Console log level. One of \fBinfo\fP, \fBnone\fP, \fBgarbage\fP,
|
|||
\fBtrace\fP, \fBwarning\fP, \fBerror\fP, \fBdebug\fP. For the logfile
|
||||
settings see the config file. Default: \fBwarning\fP.
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch@gmail.com> and many others, please see the Authors file
|
||||
.SH COPYRIGHT
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH "SALT-MINION" "1" "April 27, 2012" "0.9.9" "Salt"
|
||||
.TH "SALT-MINION" "1" "May 11, 2012" "0.9.9" "Salt"
|
||||
.SH NAME
|
||||
salt-minion \- salt-minion Documentation
|
||||
.
|
||||
|
@ -72,6 +72,11 @@ Console log level. One of \fBinfo\fP, \fBnone\fP, \fBgarbage\fP,
|
|||
\fBtrace\fP, \fBwarning\fP, \fBerror\fP, \fBdebug\fP. For the logfile
|
||||
settings see the config file. Default: \fBwarning\fP.
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt(7)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch@gmail.com> and many others, please see the Authors file
|
||||
.SH COPYRIGHT
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH "SALT-RUN" "1" "April 27, 2012" "0.9.9" "Salt"
|
||||
.TH "SALT-RUN" "1" "May 11, 2012" "0.9.9" "Salt"
|
||||
.SH NAME
|
||||
salt-run \- salt-run Documentation
|
||||
.
|
||||
|
@ -57,6 +57,11 @@ The location of the salt master configuration file, the salt master
|
|||
settings are required to know where the connections are;
|
||||
default=/etc/salt/master
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch@gmail.com> and many others, please see the Authors file
|
||||
.SH COPYRIGHT
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH "SALT-SYNDIC" "1" "April 27, 2012" "0.9.9" "Salt"
|
||||
.TH "SALT-SYNDIC" "1" "May 11, 2012" "0.9.9" "Salt"
|
||||
.SH NAME
|
||||
salt-syndic \- salt-syndic Documentation
|
||||
.
|
||||
|
@ -66,6 +66,11 @@ The master configuration file to use, the default is /etc/salt/master
|
|||
.B \-\-minion\-config=MINION_CONFIG
|
||||
The minion configuration file to use, the default is /etc/salt/minion
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fIsalt(1)\fP
|
||||
\fIsalt\-master(1)\fP
|
||||
\fIsalt\-minion(1)\fP
|
||||
.SH AUTHOR
|
||||
Thomas S. Hatch <thatch@gmail.com> and many others, please see the Authors file
|
||||
.SH COPYRIGHT
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH "SALT" "1" "April 27, 2012" "0.9.9" "Salt"
|
||||
.TH "SALT" "1" "May 11, 2012" "0.9.9" "Salt"
|
||||
.SH NAME
|
||||
salt \- salt
|
||||
.
|
||||
|
|
535
doc/man/salt.7
535
doc/man/salt.7
File diff suppressed because it is too large
Load diff
|
@ -60,3 +60,10 @@ Options
|
|||
.. option:: --no-color
|
||||
|
||||
Disable all colored output
|
||||
|
||||
See also
|
||||
========
|
||||
|
||||
:manpage:`salt(1)`
|
||||
:manpage:`salt-master(1)`
|
||||
:manpage:`salt-minion(1)`
|
||||
|
|
|
@ -78,3 +78,10 @@ Options
|
|||
The location of the salt master configuration file, the salt master
|
||||
settings are required to know where the connections are;
|
||||
default=/etc/salt/master
|
||||
|
||||
See also
|
||||
========
|
||||
|
||||
:manpage:`salt(1)`
|
||||
:manpage:`salt-master(1)`
|
||||
:manpage:`salt-minion(1)`
|
||||
|
|
|
@ -44,3 +44,10 @@ Options
|
|||
Console log level. One of ``info``, ``none``, ``garbage``,
|
||||
``trace``, ``warning``, ``error``, ``debug``. For the logfile
|
||||
settings see the config file. Default: ``warning``.
|
||||
|
||||
See also
|
||||
========
|
||||
|
||||
:manpage:`salt(1)`
|
||||
:manpage:`salt(7)`
|
||||
:manpage:`salt-minion(1)`
|
||||
|
|
|
@ -45,3 +45,10 @@ Options
|
|||
Console log level. One of ``info``, ``none``, ``garbage``,
|
||||
``trace``, ``warning``, ``error``, ``debug``. For the logfile
|
||||
settings see the config file. Default: ``warning``.
|
||||
|
||||
See also
|
||||
========
|
||||
|
||||
:manpage:`salt(1)`
|
||||
:manpage:`salt(7)`
|
||||
:manpage:`salt-master(1)`
|
||||
|
|
|
@ -32,3 +32,10 @@ Options
|
|||
The location of the salt master configuration file, the salt master
|
||||
settings are required to know where the connections are;
|
||||
default=/etc/salt/master
|
||||
|
||||
See also
|
||||
========
|
||||
|
||||
:manpage:`salt(1)`
|
||||
:manpage:`salt-master(1)`
|
||||
:manpage:`salt-minion(1)`
|
||||
|
|
|
@ -40,3 +40,10 @@ Options
|
|||
.. option:: --minion-config=MINION_CONFIG
|
||||
|
||||
The minion configuration file to use, the default is /etc/salt/minion
|
||||
|
||||
See also
|
||||
========
|
||||
|
||||
:manpage:`salt(1)`
|
||||
:manpage:`salt-master(1)`
|
||||
:manpage:`salt-minion(1)`
|
||||
|
|
|
@ -523,6 +523,17 @@ def saltversion():
|
|||
from salt import __version__
|
||||
return {'saltversion': __version__}
|
||||
|
||||
def shell():
|
||||
'''
|
||||
Return the default shell to use on this system
|
||||
'''
|
||||
# Provides:
|
||||
# shell
|
||||
ret = {'shell': '/bin/sh'}
|
||||
if 'SHELL' in os.environ:
|
||||
ret['shell'] = os.environ['SHELL']
|
||||
return ret
|
||||
|
||||
# Relatively complex mini-algorithm to iterate over the various
|
||||
# sections of dmidecode output and return matches for specific
|
||||
# lines containing data we want, but only in the right section.
|
||||
|
|
|
@ -7,10 +7,11 @@ Routines to set up a minion
|
|||
|
||||
|
||||
# Import python libs
|
||||
import imp
|
||||
import logging
|
||||
import os
|
||||
import imp
|
||||
import salt
|
||||
import logging
|
||||
import tempfile
|
||||
from salt.exceptions import LoaderError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -246,7 +247,7 @@ class Loader(object):
|
|||
return None
|
||||
try:
|
||||
if full.endswith('.pyx') and self.opts['cython_enable']:
|
||||
mod = pyximport.load_module(name, full, '/tmp')
|
||||
mod = pyximport.load_module(name, full, tempfile.gettempdir())
|
||||
else:
|
||||
fn_, path, desc = imp.find_module(name, self.module_dirs)
|
||||
mod = imp.load_module(
|
||||
|
@ -339,7 +340,7 @@ class Loader(object):
|
|||
mod = pyximport.load_module(
|
||||
'{0}_{1}'.format(name, self.tag),
|
||||
names[name],
|
||||
'/tmp')
|
||||
tempfile.gettempdir())
|
||||
else:
|
||||
fn_, path, desc = imp.find_module(name, self.module_dirs)
|
||||
mod = imp.load_module(
|
||||
|
|
|
@ -7,14 +7,15 @@ involves preparing the three listeners and the workers needed by the master.
|
|||
import os
|
||||
import re
|
||||
import time
|
||||
import errno
|
||||
import signal
|
||||
import shutil
|
||||
import logging
|
||||
import hashlib
|
||||
import tempfile
|
||||
import datetime
|
||||
import signal
|
||||
import multiprocessing
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
|
||||
# Import zeromq
|
||||
import zmq
|
||||
|
@ -32,6 +33,7 @@ import salt.client
|
|||
import salt.payload
|
||||
import salt.pillar
|
||||
import salt.state
|
||||
from salt.utils.debug import enable_sigusr1_handler
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -148,6 +150,8 @@ class Master(SMaster):
|
|||
'''
|
||||
Turn on the master server components
|
||||
'''
|
||||
enable_sigusr1_handler()
|
||||
|
||||
log.warn('Starting the Salt Master')
|
||||
clear_old_jobs_proc = multiprocessing.Process(
|
||||
target=self._clear_old_jobs)
|
||||
|
@ -219,8 +223,15 @@ class Publisher(multiprocessing.Process):
|
|||
|
||||
try:
|
||||
while True:
|
||||
package = pull_sock.recv()
|
||||
pub_sock.send(package)
|
||||
# Catch and handle EINTR from when this process is sent
|
||||
# SIGUSR1 gracefully so we don't choke and die horribly
|
||||
try:
|
||||
package = pull_sock.recv()
|
||||
pub_sock.send(package)
|
||||
except zmq.ZMQError as exc:
|
||||
if exc.errno == errno.EINTR:
|
||||
continue
|
||||
raise exc
|
||||
except KeyboardInterrupt:
|
||||
pub_sock.close()
|
||||
pull_sock.close()
|
||||
|
@ -270,7 +281,13 @@ class ReqServer(object):
|
|||
|
||||
self.workers.bind(self.w_uri)
|
||||
|
||||
zmq.device(zmq.QUEUE, self.clients, self.workers)
|
||||
while True:
|
||||
try:
|
||||
zmq.device(zmq.QUEUE, self.clients, self.workers)
|
||||
except zmq.ZMQError as exc:
|
||||
if exc.errno == errno.EINTR:
|
||||
continue
|
||||
raise exc
|
||||
|
||||
def start_publisher(self):
|
||||
'''
|
||||
|
@ -320,10 +337,16 @@ class MWorker(multiprocessing.Process):
|
|||
socket.connect(w_uri)
|
||||
|
||||
while True:
|
||||
package = socket.recv()
|
||||
payload = self.serial.loads(package)
|
||||
ret = self.serial.dumps(self._handle_payload(payload))
|
||||
socket.send(ret)
|
||||
try:
|
||||
package = socket.recv()
|
||||
payload = self.serial.loads(package)
|
||||
ret = self.serial.dumps(self._handle_payload(payload))
|
||||
socket.send(ret)
|
||||
# Properly handle EINTR from SIGUSR1
|
||||
except zmq.ZMQError as exc:
|
||||
if exc.errno == errno.EINTR:
|
||||
continue
|
||||
raise exc
|
||||
except KeyboardInterrupt:
|
||||
socket.close()
|
||||
|
||||
|
@ -976,7 +999,7 @@ class ClearFuncs(object):
|
|||
# Set up the payload
|
||||
payload = {'enc': 'aes'}
|
||||
# Altering the contents of the publish load is serious!! Changes here
|
||||
# break compatibility with minion/master versions and even tiny
|
||||
# break compatibility with minion/master versions and even tiny
|
||||
# additions can have serious implications on the performance of the
|
||||
# publish commands.
|
||||
#
|
||||
|
|
|
@ -26,6 +26,7 @@ import salt.crypt
|
|||
import salt.loader
|
||||
import salt.utils
|
||||
import salt.payload
|
||||
from salt.utils.debug import enable_sigusr1_handler
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -475,6 +476,10 @@ class Minion(object):
|
|||
socket.setsockopt(zmq.SUBSCRIBE, '')
|
||||
socket.setsockopt(zmq.IDENTITY, self.opts['id'])
|
||||
socket.connect(self.master_pub)
|
||||
|
||||
# Make sure to gracefully handle SIGUSR1
|
||||
enable_sigusr1_handler()
|
||||
|
||||
if self.opts['sub_timeout']:
|
||||
last = time.time()
|
||||
while True:
|
||||
|
|
|
@ -216,7 +216,7 @@ def purge(pkg):
|
|||
return ret_pkgs
|
||||
|
||||
|
||||
def upgrade(refresh=True):
|
||||
def upgrade(refresh=True, **kwargs):
|
||||
'''
|
||||
Upgrades all packages via ``apt-get dist-upgrade``
|
||||
|
||||
|
|
|
@ -56,6 +56,10 @@ def _run(cmd,
|
|||
if not cwd:
|
||||
cwd = os.path.expanduser('~{0}'.format('' if not runas else runas))
|
||||
|
||||
if not os.path.isfile(shell) or not os.access(shell, os.X_OK):
|
||||
msg = 'The shell {0} is not available'.format(shell)
|
||||
raise CommandExecutionError(msg)
|
||||
|
||||
# TODO: Figure out the proper way to do this in windows
|
||||
disable_runas = [
|
||||
'Windows',
|
||||
|
|
|
@ -146,7 +146,7 @@ def _interfaces_ifconfig():
|
|||
ret = {}
|
||||
|
||||
piface = re.compile('^(\w+)')
|
||||
pmac = re.compile('.*?(?:HWaddr|ether) (.*?)\s')
|
||||
pmac = re.compile('.*?(?:HWaddr|ether) ([0-9a-fA-F:]+)')
|
||||
pip = re.compile('.*?(?:inet addr:|inet )(.*?)\s')
|
||||
pip6 = re.compile('.*?(?:inet6 addr: (.*?)/|inet6 )([0-9a-fA-F:]+)')
|
||||
pmask = re.compile('.*?(?:Mask:|netmask )(?:(0x[0-9a-fA-F]{8})|([\d\.]+))')
|
||||
|
@ -393,7 +393,7 @@ def hwaddr(interface):
|
|||
salt '*' network.hwaddr eth0
|
||||
'''
|
||||
data = interfaces().get(interface)
|
||||
if data:
|
||||
if data and 'hwaddr' in data:
|
||||
return data['hwaddr']
|
||||
else:
|
||||
return None
|
||||
|
|
|
@ -30,14 +30,6 @@ syslog if there is no disk space:
|
|||
cmd:
|
||||
- run
|
||||
- unless: echo 'foo' > /tmp/.test
|
||||
|
||||
.. warning::
|
||||
|
||||
Please be advised that on Unix systems the shell being used by python
|
||||
to run executions is /bin/sh, this requires that commands are formatted
|
||||
to execute under /bin/sh. Some capabilities of newer shells such as bash,
|
||||
zsh and ksh will not always be available on minions.
|
||||
|
||||
'''
|
||||
|
||||
import grp
|
||||
|
@ -49,7 +41,8 @@ def wait(name,
|
|||
unless=None,
|
||||
cwd='/root',
|
||||
user=None,
|
||||
group=None):
|
||||
group=None,
|
||||
shell=None):
|
||||
'''
|
||||
Run the given command only if the watch statement calls it
|
||||
|
||||
|
@ -74,6 +67,9 @@ def wait(name,
|
|||
|
||||
group
|
||||
The group context to run the command as
|
||||
|
||||
shell
|
||||
The shell to use for execution, defaults to /bin/sh
|
||||
'''
|
||||
return {'name': name,
|
||||
'changes': {},
|
||||
|
@ -86,7 +82,7 @@ def run(name,
|
|||
cwd='/root',
|
||||
user=None,
|
||||
group=None,
|
||||
shell='/bin/sh',
|
||||
shell=None,
|
||||
env=()):
|
||||
'''
|
||||
Run a command if certain circumstances are met
|
||||
|
@ -112,6 +108,9 @@ def run(name,
|
|||
|
||||
group
|
||||
The group context to run the command as
|
||||
|
||||
shell
|
||||
The shell to use for execution, defaults to the shell grain
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
|
@ -147,7 +146,7 @@ def run(name,
|
|||
|
||||
cmd_kwargs = {'cwd': cwd,
|
||||
'runas': user,
|
||||
'shell': shell,
|
||||
'shell': shell or __grains__['shell'],
|
||||
'env': env}
|
||||
|
||||
if onlyif:
|
||||
|
@ -167,7 +166,7 @@ def run(name,
|
|||
try:
|
||||
cmd_all = __salt__['cmd.run_all'](name, **cmd_kwargs)
|
||||
except CommandExecutionError as e:
|
||||
ret['comment'] = e
|
||||
ret['comment'] = str(e)
|
||||
return ret
|
||||
|
||||
ret['changes'] = cmd_all
|
||||
|
|
|
@ -772,6 +772,7 @@ def managed(name,
|
|||
template=None,
|
||||
makedirs=False,
|
||||
context=None,
|
||||
replace=True,
|
||||
defaults=None,
|
||||
env=None,
|
||||
**kwargs):
|
||||
|
@ -821,6 +822,10 @@ def managed(name,
|
|||
directories will be created to facilitate the creation of the named
|
||||
file.
|
||||
|
||||
replace
|
||||
If this file should be replaced, if false then this command will
|
||||
be ignored if the file exists already. Default is true.
|
||||
|
||||
context
|
||||
Overrides default context variables passed to the template.
|
||||
|
||||
|
@ -845,6 +850,13 @@ def managed(name,
|
|||
ret['result'] = False
|
||||
return ret
|
||||
|
||||
if not replace:
|
||||
if os.path.exists(name):
|
||||
ret['comment'] = 'File {0} exists. No changes made'.format(name)
|
||||
return ret
|
||||
if not source:
|
||||
return touch(name, makedirs=makedirs)
|
||||
|
||||
if __opts__['test']:
|
||||
ret['result'], ret['comment'] = _check_managed(
|
||||
name,
|
||||
|
|
|
@ -63,7 +63,8 @@ def _changes(
|
|||
change['groups'] = groups
|
||||
if home:
|
||||
if lusr['home'] != home:
|
||||
change['home'] = home
|
||||
if not home is True:
|
||||
change['home'] = home
|
||||
if shell:
|
||||
if lusr['shell'] != shell:
|
||||
change['shell'] = shell
|
||||
|
|
43
salt/utils/debug.py
Normal file
43
salt/utils/debug.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
'''
|
||||
Print a stacktrace when sent a SIGUSR1 for debugging
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import signal
|
||||
import datetime
|
||||
import tempfile
|
||||
import traceback
|
||||
|
||||
def _makepretty(printout, stack):
|
||||
'''
|
||||
Pretty print the stack trace and environment information
|
||||
for debugging those hard to reproduce user problems. :)
|
||||
'''
|
||||
printout.write('======== Salt Debug Stack Trace =========\n')
|
||||
traceback.print_stack(stack, file=printout)
|
||||
printout.write('=========================================\n')
|
||||
|
||||
|
||||
def _handle_sigusr1(sig, stack):
|
||||
'''
|
||||
Signal handler for SIGUSR1, only available on Unix-like systems
|
||||
'''
|
||||
# When running in the foreground, do the right thing
|
||||
# and spit out the debug info straight to the console
|
||||
if sys.stderr.isatty():
|
||||
output = sys.stderr
|
||||
_makepretty(output, stack)
|
||||
else:
|
||||
filename = 'salt-debug-{0}.log'.format(int(time.time()))
|
||||
destfile = os.path.join(tempfile.gettempdir(), filename)
|
||||
with open(destfile, 'w') as output:
|
||||
_makepretty(output, stack)
|
||||
|
||||
def enable_sigusr1_handler():
|
||||
'''
|
||||
Pretty print a stack trace to the console or a debug log under /tmp
|
||||
when any of the salt daemons such as salt-master are sent a SIGUSR1
|
||||
'''
|
||||
signal.signal(signal.SIGUSR1, _handle_sigusr1)
|
|
@ -495,6 +495,9 @@ class Finder(object):
|
|||
_REQUIRES_STAT: list(),
|
||||
_REQUIRES_CONTENTS: list()}
|
||||
for key, value in options.iteritems():
|
||||
if key.startswith('_'):
|
||||
# this is a passthrough object, continue
|
||||
continue
|
||||
if value is None or len(value) == 0:
|
||||
raise ValueError('missing value for "{0}" option'.format(key))
|
||||
try:
|
||||
|
|
|
@ -36,23 +36,23 @@ class TestDaemon(object):
|
|||
Start a master and minion
|
||||
'''
|
||||
self.master_opts = salt.config.master_config(
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files/conf/master'))
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'master'))
|
||||
self.minion_opts = salt.config.minion_config(
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files/conf/minion'))
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'minion'))
|
||||
self.smaster_opts = salt.config.master_config(
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files/conf/syndic_master'))
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'syndic_master'))
|
||||
self.syndic_opts = salt.config.minion_config(
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files/conf/syndic'))
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'syndic'))
|
||||
self.syndic_opts['_master_conf_file'] = os.path.join(
|
||||
INTEGRATION_TEST_DIR,
|
||||
'files/conf/master'
|
||||
)
|
||||
# Set up config options that require internal data
|
||||
self.master_opts['pillar_roots'] = {
|
||||
'base': [os.path.join(FILES, 'pillar/base')]
|
||||
'base': [os.path.join(FILES, 'pillar', 'base')]
|
||||
}
|
||||
self.master_opts['file_roots'] = {
|
||||
'base': [os.path.join(FILES, 'file/base')]
|
||||
'base': [os.path.join(FILES, 'file', 'base')]
|
||||
}
|
||||
self.master_opts['ext_pillar'] = [
|
||||
{'cmd_yaml': 'cat {0}'.format(
|
||||
|
@ -135,7 +135,7 @@ class ModuleCase(TestCase):
|
|||
self.client = salt.client.LocalClient(
|
||||
os.path.join(
|
||||
INTEGRATION_TEST_DIR,
|
||||
'files/conf/master'
|
||||
'files', 'conf', 'master'
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -154,7 +154,7 @@ class ModuleCase(TestCase):
|
|||
return salt.config.minion_config(
|
||||
os.path.join(
|
||||
INTEGRATION_TEST_DIR,
|
||||
'files/conf/minion'
|
||||
'files', 'conf', 'minion'
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -165,7 +165,7 @@ class ModuleCase(TestCase):
|
|||
return salt.config.minion_config(
|
||||
os.path.join(
|
||||
INTEGRATION_TEST_DIR,
|
||||
'files/conf/master'
|
||||
'files', 'conf', 'master'
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -180,7 +180,7 @@ class SyndicCase(TestCase):
|
|||
self.client = salt.client.LocalClient(
|
||||
os.path.join(
|
||||
INTEGRATION_TEST_DIR,
|
||||
'files/conf/syndic_master'
|
||||
'files', 'conf', 'syndic_master'
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -216,7 +216,7 @@ class ShellCase(TestCase):
|
|||
'''
|
||||
Execute salt-key
|
||||
'''
|
||||
mconf = os.path.join(INTEGRATION_TEST_DIR, 'files/conf/master')
|
||||
mconf = os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'master')
|
||||
arg_str = '-c {0} {1}'.format(mconf, arg_str)
|
||||
return self.run_script('salt', arg_str)
|
||||
|
||||
|
@ -224,7 +224,7 @@ class ShellCase(TestCase):
|
|||
'''
|
||||
Execute salt-key
|
||||
'''
|
||||
mconf = os.path.join(INTEGRATION_TEST_DIR, 'files/conf/master')
|
||||
mconf = os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'master')
|
||||
arg_str = '-c {0} {1}'.format(mconf, arg_str)
|
||||
return self.run_script('salt-run', arg_str)
|
||||
|
||||
|
@ -232,6 +232,6 @@ class ShellCase(TestCase):
|
|||
'''
|
||||
Execute salt-key
|
||||
'''
|
||||
mconf = os.path.join(INTEGRATION_TEST_DIR, 'files/conf/master')
|
||||
mconf = os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'master')
|
||||
arg_str = '-c {0} {1}'.format(mconf, arg_str)
|
||||
return self.run_script('salt-key', arg_str)
|
||||
|
|
|
@ -32,26 +32,30 @@ class TestModulesGrains(integration.ModuleCase):
|
|||
'''
|
||||
grains.ls
|
||||
'''
|
||||
check_for = (
|
||||
'cpuarch',
|
||||
'cpu_flags',
|
||||
'cpu_model',
|
||||
'domain',
|
||||
'fqdn',
|
||||
'host',
|
||||
'kernel',
|
||||
'kernelrelease',
|
||||
'localhost',
|
||||
'mem_total',
|
||||
'num_cpus',
|
||||
'os',
|
||||
'path',
|
||||
'ps',
|
||||
'pythonpath',
|
||||
'pythonversion',
|
||||
'saltpath',
|
||||
'saltversion',
|
||||
'virtual',
|
||||
)
|
||||
lsgrains = self.run_function('grains.ls')
|
||||
self.assertTrue('cpu_model' in lsgrains)
|
||||
self.assertTrue('cpu_flags' in lsgrains)
|
||||
self.assertTrue('cpuarch' in lsgrains)
|
||||
self.assertTrue('domain' in lsgrains)
|
||||
self.assertTrue('fqdn' in lsgrains)
|
||||
self.assertTrue('host' in lsgrains)
|
||||
self.assertTrue('kernel' in lsgrains)
|
||||
self.assertTrue('kernelrelease' in lsgrains)
|
||||
self.assertTrue('localhost' in lsgrains)
|
||||
self.assertTrue('mem_total' in lsgrains)
|
||||
self.assertTrue('num_cpus' in lsgrains)
|
||||
self.assertTrue('os' in lsgrains)
|
||||
self.assertTrue('path' in lsgrains)
|
||||
self.assertTrue('ps' in lsgrains)
|
||||
self.assertTrue('pythonpath' in lsgrains)
|
||||
self.assertTrue('pythonversion' in lsgrains)
|
||||
self.assertTrue('saltpath' in lsgrains)
|
||||
self.assertTrue('saltversion' in lsgrains)
|
||||
self.assertTrue('virtual' in lsgrains)
|
||||
for grain_name in check_for:
|
||||
self.assertTrue(grain_name in lsgrains)
|
||||
|
||||
if __name__ == "__main__":
|
||||
loader = TestLoader()
|
||||
|
|
|
@ -44,17 +44,22 @@ class PublishModuleTest(integration.ModuleCase):
|
|||
'cheese=spam',
|
||||
]
|
||||
)['minion']['ret']
|
||||
self.assertTrue('__pub_arg' in ret)
|
||||
self.assertTrue('__pub_id' in ret)
|
||||
self.assertTrue('__pub_fun' in ret)
|
||||
self.assertTrue('__pub_jid' in ret)
|
||||
self.assertTrue('__pub_tgt' in ret)
|
||||
self.assertTrue('__pub_tgt_type' in ret)
|
||||
self.assertTrue('__pub_ret' in ret)
|
||||
self.assertTrue('cheese' in ret)
|
||||
self.assertEqual(ret['cheese'], 'spam')
|
||||
check_true = (
|
||||
'cheese',
|
||||
'__pub_arg',
|
||||
'__pub_fun',
|
||||
'__pub_id',
|
||||
'__pub_jid',
|
||||
'__pub_ret',
|
||||
'__pub_tgt',
|
||||
'__pub_tgt_type',
|
||||
)
|
||||
for name in check_true:
|
||||
self.assertTrue(name in ret)
|
||||
|
||||
self.assertEqual(ret['cheese'], 'spam')
|
||||
self.assertEqual(ret['__pub_arg'], ['cheese=spam'])
|
||||
self.assertEqual(ret['__pub_id'], 'minion')
|
||||
self.assertEqual(ret['__pub_id'], 'minion')
|
||||
self.assertEqual(ret['__pub_fun'], 'test.kwarg')
|
||||
|
||||
def test_reject_minion(self):
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from os import path
|
||||
from salt.utils.jinja import SaltCacheLoader, get_template
|
||||
import os
|
||||
import tempfile
|
||||
from jinja2 import Environment
|
||||
from salt.utils.jinja import SaltCacheLoader, get_template
|
||||
|
||||
from saltunittest import TestCase
|
||||
|
||||
TEMPLATES_DIR = path.dirname(path.abspath(__file__))
|
||||
TEMPLATES_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
class MockFileClient(object):
|
||||
'''
|
||||
|
@ -15,7 +16,7 @@ class MockFileClient(object):
|
|||
self.requests = []
|
||||
def get_file(self, template, dest='', makedirs=False, env='base'):
|
||||
self.requests.append({
|
||||
'path': template,
|
||||
'path': template,
|
||||
'dest': dest,
|
||||
'makedirs': makedirs,
|
||||
'env': env
|
||||
|
@ -26,8 +27,9 @@ class TestSaltCacheLoader(TestCase):
|
|||
'''
|
||||
The searchpath is based on the cachedir option and the env parameter
|
||||
'''
|
||||
loader = SaltCacheLoader({'cachedir': '/tmp'}, env='test')
|
||||
assert loader.searchpath == '/tmp/files/test'
|
||||
tmp = tempfile.gettempdir()
|
||||
loader = SaltCacheLoader({'cachedir': tmp}, env='test')
|
||||
assert loader.searchpath == os.path.join(tmp, 'files', 'test')
|
||||
def test_mockclient(self):
|
||||
'''
|
||||
A MockFileClient is used that records all file request normally send to the master.
|
||||
|
@ -37,7 +39,8 @@ class TestSaltCacheLoader(TestCase):
|
|||
res = loader.get_source(None, 'hello_simple')
|
||||
assert len(res) == 3
|
||||
self.assertEqual(res[0], 'world\n')
|
||||
self.assertEqual(res[1], '%s/files/test/hello_simple' % TEMPLATES_DIR)
|
||||
tmpl_dir = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_simple')
|
||||
self.assertEqual(res[1], tmpl_dir)
|
||||
assert res[2](), "Template up to date?"
|
||||
assert len(fc.requests)
|
||||
self.assertEqual(fc.requests[0]['path'], 'salt://hello_simple')
|
||||
|
@ -81,10 +84,10 @@ class TestSaltCacheLoader(TestCase):
|
|||
class TestGetTemplate(TestCase):
|
||||
def test_fallback(self):
|
||||
'''
|
||||
A Template without loader is returned as fallback
|
||||
A Template without loader is returned as fallback
|
||||
if the file is not contained in the searchpath
|
||||
'''
|
||||
filename = '%s/files/test/hello_simple' % TEMPLATES_DIR
|
||||
filename = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_simple')
|
||||
tmpl = get_template(filename, {'cachedir': TEMPLATES_DIR}, env='other')
|
||||
self.assertEqual(tmpl.render(), 'world')
|
||||
def test_fallback_noloader(self):
|
||||
|
@ -92,7 +95,7 @@ class TestGetTemplate(TestCase):
|
|||
If the fallback is used any attempt to load other templates
|
||||
will raise a TypeError.
|
||||
'''
|
||||
filename = '%s/files/test/hello_import' % TEMPLATES_DIR
|
||||
filename = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_import')
|
||||
tmpl = get_template(filename, {'cachedir': TEMPLATES_DIR}, env='other')
|
||||
self.assertRaises(TypeError, tmpl.render)
|
||||
def test_env(self):
|
||||
|
@ -105,8 +108,8 @@ class TestGetTemplate(TestCase):
|
|||
fc = MockFileClient()
|
||||
# monkey patch file client
|
||||
_fc = SaltCacheLoader.file_client
|
||||
SaltCacheLoader.file_client = lambda loader: fc
|
||||
filename = '%s/files/test/hello_import' % TEMPLATES_DIR
|
||||
SaltCacheLoader.file_client = lambda loader: fc
|
||||
filename = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_import')
|
||||
tmpl = get_template(filename, {'cachedir': TEMPLATES_DIR}, env='test')
|
||||
self.assertEqual(tmpl.render(a='Hi', b='Salt'), 'Hey world !Hi Salt !')
|
||||
self.assertEqual(fc.requests[0]['path'], 'salt://macro')
|
||||
|
|
Loading…
Add table
Reference in a new issue