mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 17:33:54 +00:00
Merge remote-tracking branch 'saltstack/develop' into develop
This commit is contained in:
commit
68f7ae87a2
9
debian/salt-common.dirs
vendored
9
debian/salt-common.dirs
vendored
@ -1,5 +1,4 @@
|
||||
/etc/salt
|
||||
/etc/salt/pki
|
||||
/var/cache/salt
|
||||
/var/log/salt
|
||||
/var/run/salt
|
||||
/etc/salt/
|
||||
/etc/salt/pki/
|
||||
/var/cache/salt/
|
||||
/var/log/salt/
|
||||
|
3
debian/salt-common.postrm
vendored
3
debian/salt-common.postrm
vendored
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh -e
|
||||
# Purge config files, logs, and directories created after package install.
|
||||
# Note that user-specified alternate locations for these are not affected.
|
||||
|
||||
@ -50,4 +50,5 @@ case "$1" in
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
exit 0
|
||||
|
7
debian/salt-master.dirs
vendored
7
debian/salt-master.dirs
vendored
@ -1,4 +1,3 @@
|
||||
/etc/salt/master.d
|
||||
/etc/salt/pki/master
|
||||
/var/cache/salt/master
|
||||
/var/run/salt/master
|
||||
/etc/salt/master.d/
|
||||
/etc/salt/pki/master/
|
||||
/var/cache/salt/master/
|
||||
|
3
debian/salt-master.postrm
vendored
3
debian/salt-master.postrm
vendored
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh -e
|
||||
# Purge config files, logs, and directories created after package install.
|
||||
# Note that user-specified alternate locations for these are not affected.
|
||||
|
||||
@ -50,4 +50,5 @@ case "$1" in
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
exit 0
|
||||
|
7
debian/salt-minion.dirs
vendored
7
debian/salt-minion.dirs
vendored
@ -1,4 +1,3 @@
|
||||
/etc/salt/minion.d
|
||||
/etc/salt/pki/minion
|
||||
/var/cache/salt/minion
|
||||
/var/run/salt/minion
|
||||
/etc/salt/minion.d/
|
||||
/etc/salt/pki/minion/
|
||||
/var/cache/salt/minion/
|
||||
|
3
debian/salt-minion.postrm
vendored
3
debian/salt-minion.postrm
vendored
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh -e
|
||||
# Purge config files, logs, and directories created after package install.
|
||||
# Note that user-specified alternate locations for these are not affected.
|
||||
|
||||
@ -50,4 +50,5 @@ case "$1" in
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
exit 0
|
||||
|
3
debian/salt-syndic.postrm
vendored
3
debian/salt-syndic.postrm
vendored
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh -e
|
||||
# Purge config files, logs, and directories created after package install.
|
||||
# Note that user-specified alternate locations for these are not affected.
|
||||
|
||||
@ -50,4 +50,5 @@ case "$1" in
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
exit 0
|
||||
|
@ -14,3 +14,4 @@ Full list of builtin returner modules
|
||||
cassandra_return
|
||||
mongo_return
|
||||
redis_return
|
||||
mysql
|
||||
|
6
doc/ref/returners/all/salt.returners.mysql.rst
Normal file
6
doc/ref/returners/all/salt.returners.mysql.rst
Normal file
@ -0,0 +1,6 @@
|
||||
====================
|
||||
salt.returners.mysql
|
||||
====================
|
||||
|
||||
.. automodule:: salt.returners.mysql
|
||||
:members:
|
@ -145,14 +145,23 @@ Watch and the mod_watch Function
|
||||
|
||||
The watch requisite is based on the ``mod_watch`` function. Python state
|
||||
modules can include a function called ``mod_watch`` which is then called
|
||||
if the watch call is invoked. In the case of the service module the underlying
|
||||
service is restarted. In the case of the cmd state the command is executed.
|
||||
if the watch call is invoked. When ``mod_watch`` is called depends on the
|
||||
execution of the watched state, which:
|
||||
|
||||
- If no changes then just run the watching state itself as usual.
|
||||
``mod_watch`` is not called. This behavior is same as using a ``require``.
|
||||
|
||||
- If changes then run the watching state *AND* if that changes nothing then
|
||||
react by calling ``mod_watch``.
|
||||
|
||||
When reacting, in the case of the service module the underlying service is
|
||||
restarted. In the case of the cmd state the command is executed.
|
||||
|
||||
The ``mod_watch`` function for the service state looks like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def mod_watch(name, sig=None):
|
||||
def mod_watch(name, sig=None, reload=False, full_restart=False):
|
||||
'''
|
||||
The service watcher, called to invoke the watch command.
|
||||
|
||||
@ -163,22 +172,48 @@ The ``mod_watch`` function for the service state looks like this:
|
||||
The string to search for when looking for the service process with ps
|
||||
'''
|
||||
if __salt__['service.status'](name, sig):
|
||||
changes = {name: __salt__['service.restart'](name)}
|
||||
return {'name': name,
|
||||
'changes': changes,
|
||||
'result': True,
|
||||
'comment': 'Service restarted'}
|
||||
if 'service.reload' in __salt__ and reload:
|
||||
restart_func = __salt__['service.reload']
|
||||
elif 'service.full_restart' in __salt__ and full_restart:
|
||||
restart_func = __salt__['service.full_restart']
|
||||
else:
|
||||
restart_func = __salt__['service.restart']
|
||||
else:
|
||||
restart_func = __salt__['service.start']
|
||||
|
||||
result = restart_func(name)
|
||||
return {'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': 'Service {0} started'.format(name)}
|
||||
'changes': {name: result},
|
||||
'result': result,
|
||||
'comment': 'Service restarted' if result else \
|
||||
'Failed to restart the service'
|
||||
}
|
||||
|
||||
The watch requisite only works if the state that is watching has a
|
||||
``mod_watch`` function written. If watch is set on a state that does not have
|
||||
a ``mod_watch`` function (like pkg), then the listed states will behave only
|
||||
as if they were under a ``require`` statement.
|
||||
|
||||
Also notice that a ``mod_watch`` may accept additional keyword arguments,
|
||||
which, in the sls file, will be taken from the same set of arguments specified
|
||||
for the state that includes the ``watch`` requisite. This means, for the
|
||||
earlier ``service.running`` example above, you can tell the service to
|
||||
``reload`` instead of restart like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
redis:
|
||||
|
||||
# ... other state declarations omitted ...
|
||||
|
||||
service.running:
|
||||
- enable: True
|
||||
- reload: True
|
||||
- watch:
|
||||
- file: /etc/redis.conf
|
||||
- pkg: redis
|
||||
|
||||
|
||||
The Order Option
|
||||
================
|
||||
|
||||
|
@ -4,11 +4,20 @@ Introduction to Salt
|
||||
|
||||
.. rubric:: We’re not just talking about NaCl.
|
||||
|
||||
Distributed remote execution
|
||||
============================
|
||||
The 30 second summary
|
||||
=====================
|
||||
|
||||
Salt is a distributed remote execution system used to execute commands and
|
||||
query data. It was developed in order to bring the best solutions found in the
|
||||
Salt is:
|
||||
|
||||
* a configuration management system, capable of maintaining remote nodes
|
||||
in defined states (for example, ensuring that specific packages are installed and
|
||||
specific services are running)
|
||||
|
||||
* a distributed remote execution system used to execute commands and
|
||||
query data on remote nodes, either individually or by arbitrary
|
||||
selection criteria
|
||||
|
||||
It was developed in order to bring the best solutions found in the
|
||||
world of remote execution together and make them better, faster, and more
|
||||
malleable. Salt accomplishes this through its ability to handle large loads of
|
||||
information, and not just dozens but hundreds and even thousands of individual
|
||||
@ -17,7 +26,7 @@ servers quickly through a simple and manageable interface.
|
||||
Simplicity
|
||||
==========
|
||||
|
||||
Versatility between massive scale deployments and smaller systems may seem
|
||||
Providing versatility between massive scale deployments and smaller systems may seem
|
||||
daunting, but Salt is very simple to set up and maintain, regardless of the
|
||||
size of the project. The architecture of Salt is designed to work with any
|
||||
number of servers, from a handful of local network systems to international
|
||||
@ -29,23 +38,28 @@ modification, Salt can be fine tuned to meet specific needs.
|
||||
Parallel execution
|
||||
==================
|
||||
|
||||
The core function of Salt is to enable remote commands to be called in parallel
|
||||
rather than in serial, to use a secure and encrypted protocol, the smallest and
|
||||
fastest network payloads possible, and with a simple programming interface. Salt
|
||||
also introduces more granular controls to the realm of remote execution,
|
||||
allowing for commands to be executed in parallel and for systems to be targeted
|
||||
based on more than just hostname, but by system properties.
|
||||
The core functions of Salt:
|
||||
|
||||
* enable commands to remote systems to be called in parallel rather than serially
|
||||
* use a secure and encrypted protocol
|
||||
* use the smallest and fastest network payloads possible
|
||||
* provide a simple programming interface
|
||||
|
||||
Salt also introduces more granular controls to the realm of remote
|
||||
execution, allowing systems to be targeted not just by hostname, but
|
||||
also by system properties.
|
||||
|
||||
Building on proven technology
|
||||
=============================
|
||||
|
||||
Salt takes advantage of a number of technologies and techniques. The networking
|
||||
layer is built with the excellent `ZeroMQ`_ networking library, so Salt itself
|
||||
contains a viable, and transparent, AMQ broker inside the daemon. Salt uses
|
||||
public keys for authentication with the master daemon, then uses faster `AES`_
|
||||
encryption for payload communication, this means that authentication and
|
||||
encryption are also built into Salt. Salt takes advantage of communication via
|
||||
`msgpack`_, enabling fast and light network traffic.
|
||||
Salt takes advantage of a number of technologies and techniques. The
|
||||
networking layer is built with the excellent `ZeroMQ`_ networking
|
||||
library, so the Salt daemon includes a viable and transparent AMQ
|
||||
broker. Salt uses public keys for authentication with the master
|
||||
daemon, then uses faster `AES`_ encryption for payload communication;
|
||||
authentication and encryption are integral to Salt. Salt takes
|
||||
advantage of communication via `msgpack`_, enabling fast and light
|
||||
network traffic.
|
||||
|
||||
.. _`ZeroMQ`: http://www.zeromq.org/
|
||||
.. _`msgpack`: http://msgpack.org/
|
||||
@ -55,7 +69,7 @@ Python client interface
|
||||
=======================
|
||||
|
||||
In order to allow for simple expansion, Salt execution routines can be written
|
||||
as plain Python modules and the data collected from Salt executions can be sent
|
||||
as plain Python modules. The data collected from Salt executions can be sent
|
||||
back to the master server, or to any arbitrary program. Salt can be called from
|
||||
a simple Python API, or from the command line, so that Salt can be used to
|
||||
execute one-off commands as well as operate as an integral part of a larger
|
||||
@ -64,20 +78,22 @@ application.
|
||||
Fast, flexible, scalable
|
||||
========================
|
||||
|
||||
The result is a system that can execute commands across groups of varying size,
|
||||
from very few to very many servers at considerably high speed. A system that is
|
||||
very fast, easy to set up and amazingly malleable, able to suit the needs of
|
||||
any number of servers working within the same system. Salt’s unique
|
||||
architecture brings together the best of the remote execution world, amplifies
|
||||
its capabilities and expands its range, resulting in this system that is as
|
||||
versatile as it is practical, able to suit any network.
|
||||
The result is a system that can execute commands at high speed on
|
||||
target server groups ranging from one to very many servers. Salt is
|
||||
very fast, easy to set up, amazingly malleable and provides a single
|
||||
remote execution architecture that can manage the diverse
|
||||
requirements of any number of servers. The Salt infrastructure
|
||||
brings together the best of the remote execution world, amplifies its
|
||||
capabilities and expands its range, resulting in a system that is as
|
||||
versatile as it is practical, suitable for any network.
|
||||
|
||||
Open
|
||||
====
|
||||
|
||||
Salt is developed under the `Apache 2.0 licence`_, and can be used for open and
|
||||
proprietary projects. Please submit your expansions back to the Salt project so
|
||||
that we can all benefit together as Salt grows. So, please feel free to
|
||||
sprinkle some of this around your systems and let the deliciousness come forth.
|
||||
Salt is developed under the `Apache 2.0 licence`_, and can be used for
|
||||
open and proprietary projects. Please submit your expansions back to
|
||||
the Salt project so that we can all benefit together as Salt grows.
|
||||
Please feel free to sprinkle Salt around your systems and let the
|
||||
deliciousness come forth.
|
||||
|
||||
.. _`Apache 2.0 licence`: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
8
pkg/salt-master.upstart
Normal file
8
pkg/salt-master.upstart
Normal file
@ -0,0 +1,8 @@
|
||||
description "salt-master"
|
||||
|
||||
start on (net-device-up
|
||||
and local-filesystems
|
||||
and runlevel [2345])
|
||||
stop on runlevel [!2345]
|
||||
|
||||
exec /usr/bin/salt-master >/dev/null 2>&1
|
8
pkg/salt-minion.upstart
Normal file
8
pkg/salt-minion.upstart
Normal file
@ -0,0 +1,8 @@
|
||||
description "salt-minion"
|
||||
|
||||
start on (net-device-up
|
||||
and local-filesystems
|
||||
and runlevel [2345])
|
||||
stop on runlevel [!2345]
|
||||
|
||||
exec /usr/bin/salt-minion >/dev/null 2>&1
|
11
pkg/salt-syndic.upstart
Normal file
11
pkg/salt-syndic.upstart
Normal file
@ -0,0 +1,11 @@
|
||||
description "salt-syndic"
|
||||
|
||||
start on (net-device-up
|
||||
and local-filesystems
|
||||
and runlevel [2345])
|
||||
stop on runlevel [!2345]
|
||||
|
||||
respawn limit 10 5
|
||||
respawn
|
||||
|
||||
exec /usr/bin/salt-syndic >/dev/null 2>&1
|
@ -81,6 +81,7 @@ def load_config(opts, path, env_var):
|
||||
if not os.path.isfile(path):
|
||||
template = '{0}.template'.format(path)
|
||||
if os.path.isfile(template):
|
||||
import salt.utils # Need to re-import, need to find out why
|
||||
with salt.utils.fopen(path, 'w') as out:
|
||||
with salt.utils.fopen(template, 'r') as f:
|
||||
f.readline() # skip first line
|
||||
@ -341,6 +342,7 @@ def master_config(path):
|
||||
'cluster_masters': [],
|
||||
'cluster_mode': 'paranoid',
|
||||
'range_server': 'range:80',
|
||||
'reactors': [],
|
||||
'serial': 'msgpack',
|
||||
'state_verbose': True,
|
||||
'state_output': 'full',
|
||||
|
304
salt/modules/parted.py
Normal file
304
salt/modules/parted.py
Normal file
@ -0,0 +1,304 @@
|
||||
'''
|
||||
Module for managing partitions on posix-like systems.
|
||||
|
||||
Some functions may not be available, depending on your version of parted.
|
||||
|
||||
Check man 8 parted for more information, or the online docs at:
|
||||
|
||||
http://www.gnu.org/software/parted/manual/html_chapter/parted_2.html
|
||||
'''
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only work on posix-like systems
|
||||
'''
|
||||
# Disable on these platorms, specific service modules exist:
|
||||
disable = [
|
||||
'Windows',
|
||||
]
|
||||
if __grains__['os'] in disable:
|
||||
return False
|
||||
return 'partition'
|
||||
|
||||
|
||||
def probe(device=''):
|
||||
'''
|
||||
Ask the kernel to update its local partition data
|
||||
|
||||
CLI Examples::
|
||||
|
||||
salt '*' partition.probe
|
||||
salt '*' partition.probe /dev/sda
|
||||
'''
|
||||
cmd = 'partprobe {0}'.format(device)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def part_list(device, unit=None):
|
||||
'''
|
||||
Ask the kernel to update its local partition data
|
||||
|
||||
CLI Examples::
|
||||
|
||||
salt '*' partition.partlist /dev/sda
|
||||
salt '*' partition.partlist /dev/sda unit=s
|
||||
salt '*' partition.partlist /dev/sda unit=kB
|
||||
'''
|
||||
if unit:
|
||||
cmd = 'parted -m -s {0} unit {1} print'.format(device, unit)
|
||||
else:
|
||||
cmd = 'parted -m -s {0} print'.format(device)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
ret = {'info': {}, 'partitions': {}}
|
||||
mode = 'info'
|
||||
for line in out:
|
||||
if line.startswith('BYT'):
|
||||
continue
|
||||
comps = line.replace(';', '').split(':')
|
||||
if mode == 'info':
|
||||
if len(comps) == 8:
|
||||
ret['info'] = {
|
||||
'disk': comps[0],
|
||||
'size': comps[1],
|
||||
'interface': comps[2],
|
||||
'logical sector': comps[3],
|
||||
'physical sector': comps[4],
|
||||
'partition table': comps[5],
|
||||
'model': comps[6],
|
||||
'disk flags': comps[7]}
|
||||
mode = 'partitions'
|
||||
else:
|
||||
ret['partitions'][comps[0]] = {
|
||||
'number': comps[0],
|
||||
'start': comps[1],
|
||||
'end': comps[2],
|
||||
'size': comps[3],
|
||||
'type': comps[4],
|
||||
'file system': comps[5],
|
||||
'flags': comps[6]}
|
||||
return ret
|
||||
|
||||
|
||||
def align_check(device, part_type, partition):
|
||||
'''
|
||||
partition.align_check device part_type partition
|
||||
|
||||
Check if partition satisfies the alignment constraint of part_type.
|
||||
Type must be "minimal" or "optimal".
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.align_check /dev/sda minimal 1
|
||||
'''
|
||||
cmd = 'parted -m -s {0} align-check {1} {2}'.format(device, part_type, partition)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def check(device, minor):
|
||||
'''
|
||||
partition.check device minor
|
||||
|
||||
Checks if the file system on partition <minor> has any errors.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.check 1
|
||||
'''
|
||||
cmd = 'parted -m -s {0} check {1}'.format(device, minor)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def cp(device, from_minor, to_minor):
|
||||
'''
|
||||
partition.check device from_minor to_minor
|
||||
|
||||
Copies the file system on the partition <from-minor> to partition
|
||||
<to-minor>, deleting the original contents of the destination
|
||||
partition.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.cp /dev/sda 2 3
|
||||
'''
|
||||
cmd = 'parted -m -s {0} cp {1} {2}'.format(device, from_minor, to_minor)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def mkfs(device, minor, fs_type):
|
||||
'''
|
||||
partition.mkfs device minor fs_type
|
||||
|
||||
Makes a file system <fs_type> on partition <minor>, destroying all data
|
||||
that resides on that partition. <fs_type> must be one of "ext2",
|
||||
"fat32", "fat16", "linux-swap" or "reiserfs" (if libreiserfs is
|
||||
installed)
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.mkfs 2 fat32
|
||||
'''
|
||||
cmd = 'parted -m -s {0} mklabel {1}'.format(device, label_type)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def mklabel(device, label_type):
|
||||
'''
|
||||
partition.mklabel device label_type
|
||||
|
||||
Create a new disklabel (partition table) of label_type.
|
||||
Type should be one of "aix", "amiga", "bsd", "dvh", "gpt", "loop", "mac",
|
||||
"msdos", "pc98", or "sun".
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.mklabel /dev/sda msdos
|
||||
'''
|
||||
cmd = 'parted -m -s {0} mklabel {1}'.format(device, label_type)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def mkpart(device, part_type, fs_type, start, end):
|
||||
'''
|
||||
partition.mkpart device part_type fs_type start end
|
||||
|
||||
Make a part_type partition for filesystem fs_type, beginning at start and
|
||||
ending at end (by default in megabytes). part_type should be one of
|
||||
"primary", "logical", or "extended".
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.mkpart /dev/sda primary fat32 0 639
|
||||
'''
|
||||
cmd = 'parted -m -s {0} mkpart {1} {2} {3} {4}'.format(device, part_type, fs_type, start, end)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def mkpartfs(device, part_type, fs_type, start, end):
|
||||
'''
|
||||
partition.mkpartfs device part_type fs_type start end
|
||||
|
||||
Make a <part_type> partition with a new filesystem of <fs_type>, beginning
|
||||
at <start> and ending at <end> (by default in megabytes). <part_type>
|
||||
should be one of "primary", "logical", or "extended". <fs_type> must be
|
||||
one of "ext2", "fat32", "fat16", "linux-swap" or "reiserfs" (if
|
||||
libreiserfs is installed)
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.mkpartfs /dev/sda logical ext2 440 670
|
||||
'''
|
||||
cmd = 'parted -m -s {0} mkpart {1} {2} {3} {4}'.format(device, part_type, fs_type, start, end)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def name(device, partition, name):
|
||||
'''
|
||||
partition.name device partition name
|
||||
|
||||
Set the name of partition to name. This option works only on Mac, PC98,
|
||||
and GPT disklabels. The name can be placed in quotes, if necessary.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.name /dev/sda 1 'My Documents'
|
||||
'''
|
||||
cmd = 'parted -m -s {0} name {1} {2}'.format(device, partition, name)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def rescue(device, start, end):
|
||||
'''
|
||||
partition.rescue device start end
|
||||
|
||||
Rescue a lost partition that was located somewhere between start and end.
|
||||
If a partition is found, parted will ask if you want to create an
|
||||
entry for it in the partition table.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.rescue /dev/sda 0 8056
|
||||
'''
|
||||
cmd = 'parted -m -s {0} rescue {1} {2}'.format(device, start, end)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def resize(device, minor, start, end):
|
||||
'''
|
||||
partition.resize device minor, start, end
|
||||
|
||||
Resizes the partition with number <minor>. The partition will start <start>
|
||||
from the beginning of the disk, and end <end> from the beginning of the
|
||||
disk. resize never changes the minor number. Extended partitions can be
|
||||
resized, so long as the new extended partition completely contains all
|
||||
logical partitions.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.resize /dev/sda 3 200 850
|
||||
'''
|
||||
cmd = 'parted -m -s {0} resize {1} {2} {3}'.format(device, minor, start, end)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def rm(device, minor):
|
||||
'''
|
||||
partition.rm device minor
|
||||
|
||||
Removes the partition with number <minor>.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.rm /dev/sda 5
|
||||
'''
|
||||
cmd = 'parted -m -s {0} rm {1}'.format(device, minor)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def set(device, minor, flag, state):
|
||||
'''
|
||||
partition.set device minor flag state
|
||||
|
||||
Changes a flag on the partition with number <minor>. A flag can be either
|
||||
"on" or "off". Some or all of these flags will be available, depending
|
||||
on what disk label you are using.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.set /dev/sda 1 boot on
|
||||
'''
|
||||
cmd = 'parted -m -s {0} set {1} {2} {3}'.format(device, minor, flag, state)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def toggle(device, partition, flag):
|
||||
'''
|
||||
partition.toggle device partition flag
|
||||
|
||||
Toggle the state of <flag> on <partition>
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' partition.name /dev/sda 1 boot
|
||||
'''
|
||||
cmd = 'parted -m -s {0} toggle {1} {2} {3}'.format(device, partition, flag)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
@ -1,75 +0,0 @@
|
||||
'''
|
||||
Module for managing partitions on posix-like systems
|
||||
'''
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only work on posix-like systems
|
||||
'''
|
||||
# Disable on these platorms, specific service modules exist:
|
||||
disable = [
|
||||
'Windows',
|
||||
]
|
||||
if __grains__['os'] in disable:
|
||||
return False
|
||||
return 'partition'
|
||||
|
||||
|
||||
def probe(device=''):
|
||||
'''
|
||||
Ask the kernel to update its local partition data
|
||||
|
||||
CLI Examples::
|
||||
|
||||
salt '*' partition.probe
|
||||
salt '*' partition.probe /dev/sda
|
||||
'''
|
||||
cmd = 'partprobe {0}'.format(device)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
return out
|
||||
|
||||
|
||||
def partlist(device, unit=None):
|
||||
'''
|
||||
Ask the kernel to update its local partition data
|
||||
|
||||
CLI Examples::
|
||||
|
||||
salt '*' partition.partlist /dev/sda
|
||||
salt '*' partition.partlist /dev/sda unit=s
|
||||
salt '*' partition.partlist /dev/sda unit=kB
|
||||
'''
|
||||
if unit:
|
||||
cmd = 'parted -s {0} unit {1} print'.format(device, unit)
|
||||
else:
|
||||
cmd = 'parted -s {0} print'.format(device)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
ret = {'info': [], 'partitions': {}}
|
||||
mode = 'info'
|
||||
for line in out:
|
||||
if not line:
|
||||
continue
|
||||
if mode == 'info':
|
||||
if line.startswith('Number'):
|
||||
mode = 'partitions'
|
||||
else:
|
||||
ret['info'].append(line)
|
||||
else:
|
||||
comps = line.strip().split()
|
||||
ret['partitions'][comps[0]] = {
|
||||
'number': comps[0],
|
||||
'start': comps[1],
|
||||
'end': comps[2],
|
||||
'size': comps[3],
|
||||
'type': comps[4]}
|
||||
if len(comps) > 5:
|
||||
ret['partitions'][comps[0]]['file system'] = comps[5]
|
||||
if len(comps) > 6:
|
||||
ret['partitions'][comps[0]]['flags'] = comps[6:]
|
||||
return ret
|
||||
|
@ -81,9 +81,9 @@ def add(name,
|
||||
cmd = 'useradd '
|
||||
if shell:
|
||||
cmd += '-s {0} '.format(shell)
|
||||
if uid is not None:
|
||||
if uid not in (None, ''):
|
||||
cmd += '-u {0} '.format(uid)
|
||||
if gid is not None:
|
||||
if gid not in (None, ''):
|
||||
cmd += '-g {0} '.format(gid)
|
||||
if groups:
|
||||
cmd += '-G {0} '.format(','.join(groups))
|
||||
|
@ -28,7 +28,8 @@ def render(template_file, env='', sls='', argline='',
|
||||
env=env,
|
||||
sls=sls,
|
||||
context=context,
|
||||
tmplpath=tmplpath)
|
||||
tmplpath=tmplpath,
|
||||
**kws)
|
||||
if not tmp_data.get('result', False):
|
||||
raise SaltRenderError(tmp_data.get('data',
|
||||
'Unknown render error in jinja renderer'))
|
||||
|
@ -19,7 +19,8 @@ def render(template_file, env='', sls='', context=None, tmplpath=None, **kws):
|
||||
env=env,
|
||||
sls=sls,
|
||||
context=context,
|
||||
tmplpath=tmplpath)
|
||||
tmplpath=tmplpath,
|
||||
**kws)
|
||||
if not tmp_data.get('result', False):
|
||||
raise SaltRenderError(tmp_data.get('data',
|
||||
'Unknown render error in mako renderer'))
|
||||
|
@ -31,7 +31,8 @@ def render(template, env='', sls='', tmplpath=None, **kws):
|
||||
opts=__opts__,
|
||||
pillar=__pillar__,
|
||||
env=env,
|
||||
sls=sls)
|
||||
sls=sls,
|
||||
**kws)
|
||||
if not tmp_data.get('result', False):
|
||||
raise SaltRenderError(tmp_data.get('data',
|
||||
'Unknown render error in py renderer'))
|
||||
|
@ -4,7 +4,16 @@ specified templating engine(eg, jinja) and a chosen data renderer(eg, yaml),
|
||||
extract arguments for any ``stateconf.set`` state and provide the extracted
|
||||
arguments (including salt specific args, such as 'require', etc) as template
|
||||
context. The goal is to make writing reusable/configurable/ parameterized
|
||||
salt files easier and cleaner, therefore, additionally, it also:
|
||||
salt files easier and cleaner.
|
||||
|
||||
To use this renderer, either set it as the default renderer via the
|
||||
``renderer`` option in master/minion's config, or use the shebang line in each
|
||||
individual sls file, like so: ``#!stateconf``. Note, due to the way this
|
||||
renderer works, it must be specified as the first renderer in a render
|
||||
pipeline. That is, you cannot specify ``#!mako|yaml|stateconf``, for example.
|
||||
Instead, you specify them as renderer arguments: ``#!stateconf mako . yaml``.
|
||||
|
||||
Here's a list of features enabled by this renderer:
|
||||
|
||||
- Recognizes the special state function, ``stateconf.set``, that configures a
|
||||
default list of named arguments useable within the template context of
|
||||
@ -26,18 +35,53 @@ salt files easier and cleaner, therefore, additionally, it also:
|
||||
output:
|
||||
cmd.run:
|
||||
- name: |
|
||||
echo 'name1=${sls_params.name1}
|
||||
name2=${sls_params.name2}
|
||||
name3[1]=${sls_params.name3[1]}
|
||||
echo 'name1={{sls_params.name1}}
|
||||
name2={{sls_params.name2}}
|
||||
name3[1]={{sls_params.name3[1]}}
|
||||
'
|
||||
|
||||
This even works with ``include`` + ``extend`` so that you can override
|
||||
the default configured arguments by including the salt file and then extend
|
||||
the ``stateconf.set`` states that come from the included salt file.
|
||||
the default configured arguments by including the salt file and then
|
||||
``extend`` the ``stateconf.set`` states that come from the included salt
|
||||
file.
|
||||
|
||||
Notice that the end of configuration marker(``# --- end of state config --``)
|
||||
is needed to separate the use of 'stateconf.set' form the rest of your salt
|
||||
file.
|
||||
file. The regex that matches such marker can be configured via the
|
||||
``stateconf_end_marker`` option in your master or minion config file.
|
||||
|
||||
Sometimes, you'd like to set a default argument value that's based on
|
||||
earlier arguments in the same ``stateconf.set``. For example, you may be
|
||||
tempted to do something like this::
|
||||
|
||||
apache:
|
||||
stateconf.set:
|
||||
- host: localhost
|
||||
- port: 1234
|
||||
- url: 'http://{{host}}:{{port}}/'
|
||||
|
||||
# --- end of state config ---
|
||||
|
||||
test:
|
||||
cmd.run:
|
||||
- name: echo '{{apache.url}}'
|
||||
- cwd: /
|
||||
|
||||
However, this won't work, but can be worked around like so::
|
||||
|
||||
apache:
|
||||
stateconf.set:
|
||||
- host: localhost
|
||||
- port: 1234
|
||||
{# - url: 'http://{{host}}:{{port}}/' #}
|
||||
|
||||
# --- end of state config ---
|
||||
# {{ apache.setdefault('url', "http://%(host)s:%(port)s/" % apache) }}
|
||||
|
||||
test:
|
||||
cmd.run:
|
||||
- name: echo '{{apache.url}}'
|
||||
- cwd: /
|
||||
|
||||
- Adds support for relative include and exclude of .sls files. Example::
|
||||
|
||||
@ -81,7 +125,7 @@ salt files easier and cleaner, therefore, additionally, it also:
|
||||
package.installed:
|
||||
- name: vim
|
||||
|
||||
Notice how that if a state under a dot-prefixed state id has no 'name'
|
||||
Notice how that if a state under a dot-prefixed state id has no ``name``
|
||||
argument then one will be added automatically by using the state id with
|
||||
the leading dot stripped off.
|
||||
|
||||
@ -107,9 +151,12 @@ salt files easier and cleaner, therefore, additionally, it also:
|
||||
stateconf.set:
|
||||
- name1: something
|
||||
|
||||
- Optionally(disable via the `-G` renderer option), generates a
|
||||
``stateconf.set`` goal state(state id named as ``.goal`` by default) that
|
||||
requires all other states in the salt file.
|
||||
- Optionally(enabled by default, *disable* via the `-G` renderer option,
|
||||
eg, in the shebang line: ``#!stateconf -G``), generates a
|
||||
``stateconf.set`` goal state(state id named as ``.goal`` by default,
|
||||
configurable via the master/minion config option, ``stateconf_goal_state``)
|
||||
that requires all other states in the salt file. Note, the ``.goal``
|
||||
state id is subject to dot-prefix rename rule mentioned earlier.
|
||||
|
||||
Such goal state is intended to be required by some state in an including
|
||||
salt file. For example, in your webapp salt file, if you include a
|
||||
@ -117,10 +164,13 @@ salt files easier and cleaner, therefore, additionally, it also:
|
||||
all states in the Tomcat sls file will be executed before some state in
|
||||
the webapp sls file.
|
||||
|
||||
- Optionally(enable via the `-o` renderer option), orders the states in a sls
|
||||
file by adding a `require`` requisite to each state such that every state
|
||||
requires the state defined just before it. The order of the states here is
|
||||
the order they are defined in the sls file.
|
||||
- Optionally(enable via the `-o` renderer option, eg, in the shebang line:
|
||||
``#!stateconf -o``), orders the states in a sls file by adding a
|
||||
``require`` requisite to each state such that every state requires the
|
||||
state defined just before it. The order of the states here is the order
|
||||
they are defined in the sls file.(Note: this feature is only available
|
||||
if your minions are using Python >= 2.7. For Python2.6, it should also
|
||||
work if you install the `ordereddict` module from PyPI)
|
||||
|
||||
By enabling this feature, you are basically agreeing to author your sls
|
||||
files in a way that gives up the explicit(or implicit?) ordering imposed
|
||||
@ -130,7 +180,7 @@ salt files easier and cleaner, therefore, additionally, it also:
|
||||
there are many states defined in a sls file, then it tends to be easier
|
||||
to see the order they will be executed with this feature.
|
||||
|
||||
You are still allow to use all the requisites, with a few restricitons.
|
||||
You are still allowed to use all the requisites, with a few restricitons.
|
||||
You cannot ``require`` or ``watch`` a state defined *after* the current
|
||||
state. Similarly, in a state, you cannot ``require_in`` or ``watch_in``
|
||||
a state defined *before* it. Breaking any of the two restrictions above
|
||||
@ -140,7 +190,9 @@ salt files easier and cleaner, therefore, additionally, it also:
|
||||
Additionally, ``names`` declarations cannot be used with this feature
|
||||
because the way they are compiled into low states make it impossible to
|
||||
guarantee the order in which they will be executed. This is also checked
|
||||
by the renderer.
|
||||
by the renderer. As a workaround for not being able to use ``names``,
|
||||
you can achieve the same effect, by generate your states with the
|
||||
template engine available within your sls file.
|
||||
|
||||
Finally, with the use of this feature, it becomes possible to easily make
|
||||
an included sls file execute all its states *after* some state(say, with
|
||||
@ -149,48 +201,61 @@ salt files easier and cleaner, therefore, additionally, it also:
|
||||
|
||||
|
||||
When writing sls files with this renderer, you should avoid using what can be
|
||||
defined in a ``name`` argument of a state as the state's id. Instead, you
|
||||
should define the state id and the name argument separately for each state,
|
||||
and the id should be something meaningful and easy to reference within a
|
||||
requisite, and when referencing a state from a requisite, you should reference
|
||||
the state's id rather than its name. The reason is that this renderer might
|
||||
re-write or renames state id's and their references.
|
||||
defined in a ``name`` argument of a state as the state's id. That is, avoid
|
||||
writing your states like this::
|
||||
|
||||
/path/to/some/file:
|
||||
file.managed:
|
||||
- source: salt://some/file
|
||||
|
||||
cp /path/to/some/file file2:
|
||||
cmd.run:
|
||||
- cwd: /
|
||||
- require:
|
||||
- file: /path/to/some/file
|
||||
|
||||
Instead, you should define the state id and the ``name`` argument separately
|
||||
for each state, and the id should be something meaningful and easy to reference
|
||||
within a requisite(which I think is a good habit anyway, and such extra
|
||||
indirection would also makes your sls file easier to modify later). Thus, the
|
||||
above states should be written like this::
|
||||
|
||||
add-some-file:
|
||||
file.managed:
|
||||
- name: /path/to/some/file
|
||||
- source: salt://some/file
|
||||
|
||||
copy-files:
|
||||
cmd.run:
|
||||
- name: cp /path/to/some/file file2
|
||||
- cwd: /
|
||||
- require:
|
||||
- file: add-some-file
|
||||
|
||||
Moreover, when referencing a state from a requisite, you should reference the
|
||||
state's id plus the state name rather than the state name plus its ``name``
|
||||
argument. (Yes, in the above example, you can actually ``require`` the
|
||||
``file: /path/to/some/file``, instead of the ``file: add-some-file``). The
|
||||
reason is that this renderer will re-write or rename state id's and their
|
||||
references for state id's prefixed with ``.``. So, if you reference ``name``
|
||||
then there's no way to reliably rewrite such reference.
|
||||
|
||||
'''
|
||||
|
||||
# TODO:
|
||||
# - sls meta/info state: Eg,
|
||||
#
|
||||
# sls_info:
|
||||
# author: Jack Kuan
|
||||
# description: what the salt file does...
|
||||
# version: 0.1.0
|
||||
# stateconf.set:
|
||||
# - author: Jack Kuan
|
||||
# - description: what the salt file does...
|
||||
# - version: 0.1.0
|
||||
#
|
||||
# - version constraint for 'include'. Eg,
|
||||
#
|
||||
# include:
|
||||
# - apache: >= 0.1.0
|
||||
#
|
||||
# - support synthetic argument? Eg,
|
||||
#
|
||||
# apache:
|
||||
# stateconf.set:
|
||||
# - host: localhost
|
||||
# - port: 1234
|
||||
# - url: 'http://${host}:${port}/'
|
||||
#
|
||||
# Currently, this won't work, but can be worked around like so:
|
||||
#
|
||||
# apache:
|
||||
# stateconf.set:
|
||||
# - host: localhost
|
||||
# - port: 1234
|
||||
# ## - url: 'http://${host}:${port}/'
|
||||
#
|
||||
# # --- end of state config ---
|
||||
# <%
|
||||
# apache.setdefault('url', "http://%(host)s:%(port)s/" % apache)
|
||||
# %>
|
||||
#
|
||||
|
||||
# Import python libs
|
||||
import sys
|
||||
@ -206,6 +271,7 @@ import salt.utils
|
||||
from salt.renderers.yaml import HAS_ORDERED_DICT
|
||||
from salt.exceptions import SaltRenderError
|
||||
|
||||
__all__ = [ 'render' ]
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -18,7 +18,8 @@ def render(template_file, env='', sls='', argline='', context=None, **kws):
|
||||
pillar=__pillar__,
|
||||
env=env,
|
||||
sls=sls,
|
||||
context=context)
|
||||
context=context,
|
||||
**kws)
|
||||
if not tmp_data.get('result', False):
|
||||
raise SaltRenderError(tmp_data.get('data',
|
||||
'Unknown render error in the wempy renderer'))
|
||||
|
@ -3,7 +3,7 @@ Return data to a mysql server
|
||||
|
||||
To enable this returner the minion will need the python client for mysql
|
||||
installed and the following values configured in the minion or master
|
||||
config, these are the defaults:
|
||||
config, these are the defaults::
|
||||
|
||||
mysql.host: 'salt'
|
||||
mysql.user: 'salt'
|
||||
@ -11,42 +11,43 @@ config, these are the defaults:
|
||||
mysql.db: 'salt'
|
||||
mysql.port: 3306
|
||||
|
||||
Use the following mysql database schema:
|
||||
Use the following mysql database schema::
|
||||
|
||||
CREATE DATABASE `salt`
|
||||
DEFAULT CHARACTER SET utf8
|
||||
DEFAULT COLLATE utf8_general_ci;
|
||||
CREATE DATABASE `salt`
|
||||
DEFAULT CHARACTER SET utf8
|
||||
DEFAULT COLLATE utf8_general_ci;
|
||||
|
||||
USE `salt`;
|
||||
USE `salt`;
|
||||
|
||||
--
|
||||
-- Table structure for table `jids`
|
||||
--
|
||||
--
|
||||
-- Table structure for table `jids`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `jids`;
|
||||
CREATE TABLE `jids` (
|
||||
`jid` varchar(255) NOT NULL,
|
||||
`load` varchar(65000) NOT NULL,
|
||||
UNIQUE KEY `jid` (`jid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
DROP TABLE IF EXISTS `jids`;
|
||||
CREATE TABLE `jids` (
|
||||
`jid` varchar(255) NOT NULL,
|
||||
`load` varchar(65000) NOT NULL,
|
||||
UNIQUE KEY `jid` (`jid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table structure for table `salt_returns`
|
||||
--
|
||||
--
|
||||
-- Table structure for table `salt_returns`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `salt_returns`;
|
||||
CREATE TABLE `salt_returns` (
|
||||
`fun` varchar(50) NOT NULL,
|
||||
`jid` varchar(200) NOT NULL,
|
||||
`return` mediumtext NOT NULL,
|
||||
`id` varchar(255) NOT NULL,
|
||||
`success` varchar(10) NOT NULL,
|
||||
`full_ret` mediumtext NOT NULL,
|
||||
KEY `id` (`id`),
|
||||
KEY `jid` (`jid`),
|
||||
KEY `fun` (`fun`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
DROP TABLE IF EXISTS `salt_returns`;
|
||||
CREATE TABLE `salt_returns` (
|
||||
`fun` varchar(50) NOT NULL,
|
||||
`jid` varchar(200) NOT NULL,
|
||||
`return` mediumtext NOT NULL,
|
||||
`id` varchar(255) NOT NULL,
|
||||
`success` varchar(10) NOT NULL,
|
||||
`full_ret` mediumtext NOT NULL,
|
||||
KEY `id` (`id`),
|
||||
KEY `jid` (`jid`),
|
||||
KEY `fun` (`fun`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
Required python modules: MySQLdb
|
||||
'''
|
||||
|
||||
# Import python libs
|
@ -14,6 +14,8 @@ Manage events
|
||||
#
|
||||
# Import Python libs
|
||||
import os
|
||||
import fnmatch
|
||||
import glob
|
||||
import hashlib
|
||||
import errno
|
||||
import logging
|
||||
@ -24,6 +26,8 @@ import zmq
|
||||
|
||||
# Import Salt libs
|
||||
import salt.payload
|
||||
import salt.loader
|
||||
from salt.template import compile_template
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -213,3 +217,59 @@ class EventPublisher(multiprocessing.Process):
|
||||
except KeyboardInterrupt:
|
||||
epub_sock.close()
|
||||
epull_sock.close()
|
||||
|
||||
|
||||
class Reactor(object):
|
||||
'''
|
||||
Read in the reactor configuration variable and compare it to events
|
||||
processed on the master.
|
||||
The reactor has the capability to execute pre-programmed executions
|
||||
as reactions to events
|
||||
'''
|
||||
def __init__(self, opts):
|
||||
self.opts = opts
|
||||
self.rend = salt.loader.render(self.opts, {})
|
||||
|
||||
def render_reaction(self, glob_ref, tag, data):
|
||||
'''
|
||||
Execute the render system against a single reaction file and return
|
||||
the data structure
|
||||
'''
|
||||
react = {}
|
||||
for fn_ in glob.glob(glob_ref):
|
||||
react.update(compile_template(
|
||||
fn_,
|
||||
self.rend,
|
||||
self.opts['renderer'],
|
||||
tag=tag,
|
||||
data=data))
|
||||
return react
|
||||
|
||||
def list_reactors(self, tag):
|
||||
'''
|
||||
Take in the tag and the data from an event and return a list of the
|
||||
reactors to process
|
||||
'''
|
||||
reactors = []
|
||||
for ropt in opts['reactors']:
|
||||
if not isinstance(ropt, dict):
|
||||
continue
|
||||
if not len(ropt) == 1:
|
||||
continue
|
||||
key = ropt.keys()[0]
|
||||
val = ropt[key]
|
||||
if fnmatch.fnmatch(tag, key):
|
||||
if isinstance(val, str):
|
||||
reactors.append(val)
|
||||
elif isinstance(val, list):
|
||||
reactors.extend(val)
|
||||
return reactors
|
||||
|
||||
def reactions(self, tag, data, reactors):
|
||||
'''
|
||||
Render a list of reactor files and returns a reaction struct
|
||||
'''
|
||||
react = {}
|
||||
for fn_ in reactors:
|
||||
react.update(self.render_reaction(fn_, tag, data))
|
||||
return react
|
||||
|
@ -11,6 +11,7 @@ import os
|
||||
import sys
|
||||
import logging
|
||||
import optparse
|
||||
import traceback
|
||||
from functools import partial
|
||||
from salt import config, loader, log, version
|
||||
|
||||
@ -116,7 +117,7 @@ class OptionParser(optparse.OptionParser):
|
||||
process_option_func()
|
||||
except Exception, err:
|
||||
self.error('Error while processing {0}: {1}'.format(
|
||||
process_option_func, err
|
||||
process_option_func, traceback.format_exc(err)
|
||||
))
|
||||
|
||||
# Run the functions on self._mixin_after_parsed_funcs
|
||||
@ -1099,7 +1100,10 @@ class SaltCallOptionParser(OptionParser, ConfigDirMixIn, LogLevelMixIn,
|
||||
self.config['arg'] = self.args[1:]
|
||||
|
||||
def setup_config(self):
|
||||
return config.minion_config(self.get_config_file_path('minion'))
|
||||
return config.minion_config(
|
||||
self.get_config_file_path('minion'),
|
||||
check_dns=not self.options.local
|
||||
)
|
||||
|
||||
def process_module_dirs(self):
|
||||
if self.options.module_dirs:
|
||||
|
@ -24,7 +24,7 @@ import salt.minion
|
||||
import salt.runner
|
||||
from salt.utils import get_colors
|
||||
from salt.utils.verify import verify_env
|
||||
from saltunittest import TestCase
|
||||
from saltunittest import TestCase, RedirectStdStreams
|
||||
|
||||
try:
|
||||
import console
|
||||
@ -641,8 +641,9 @@ class ShellCase(TestCase):
|
||||
os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'master')
|
||||
)
|
||||
opts.update({'doc': False, 'fun': fun, 'arg': arg})
|
||||
runner = salt.runner.Runner(opts)
|
||||
ret['fun'] = runner.run()
|
||||
with RedirectStdStreams():
|
||||
runner = salt.runner.Runner(opts)
|
||||
ret['fun'] = runner.run()
|
||||
return ret
|
||||
|
||||
def run_key(self, arg_str, catch_stderr=False):
|
||||
|
@ -55,6 +55,50 @@ def destructiveTest(func):
|
||||
return wrap
|
||||
|
||||
|
||||
class RedirectStdStreams(object):
|
||||
"""
|
||||
Temporarily redirect system output to file like objects.
|
||||
Default is to redirect to `os.devnull`, which just mutes output, `stdout`
|
||||
and `stderr`.
|
||||
"""
|
||||
|
||||
def __init__(self, stdout=None, stderr=None):
|
||||
if stdout is None:
|
||||
stdout = open(os.devnull, 'w')
|
||||
if stderr is None:
|
||||
stderr = open(os.devnull, 'w')
|
||||
|
||||
self.__stdout = stdout
|
||||
self.__stderr = stderr
|
||||
self.__redirected = False
|
||||
|
||||
def __enter__(self):
|
||||
self.redirect()
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.unredirect()
|
||||
|
||||
def redirect(self):
|
||||
self.old_stdout = sys.stdout
|
||||
self.old_stdout.flush()
|
||||
self.old_stderr = sys.stderr
|
||||
self.old_stderr.flush()
|
||||
sys.stdout = self.__stdout
|
||||
sys.stderr = self.__stderr
|
||||
self.__redirected = True
|
||||
|
||||
def unredirect(self):
|
||||
if not self.__redirected:
|
||||
return
|
||||
|
||||
self.__stdout.flush()
|
||||
self.__stdout.close()
|
||||
self.__stderr.flush()
|
||||
self.__stderr.close()
|
||||
sys.stdout = self.old_stdout
|
||||
sys.stderr = self.old_stderr
|
||||
|
||||
|
||||
class TestsLoggingHandler(object):
|
||||
'''
|
||||
Simple logging handler which can be used to test if certain logging
|
||||
|
Loading…
Reference in New Issue
Block a user