mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge branch 'develop' of github.com:saltstack/salt into random-module-updates
Conflicts: salt/modules/ssh.py
This commit is contained in:
commit
58d0dd4ce6
81
debian/README.rst
vendored
81
debian/README.rst
vendored
@ -1,81 +0,0 @@
|
||||
=============
|
||||
What is Salt?
|
||||
=============
|
||||
|
||||
.. rubric:: We’re not just talking about NaCl.
|
||||
|
||||
Distributed remote execution
|
||||
============================
|
||||
|
||||
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
|
||||
world of remote execution together and make them better, faster and more
|
||||
malleable. Salt accomplishes this via its ability to handle larger loads of
|
||||
information, and not just dozens, but hundreds or even thousands of individual
|
||||
servers, handle them quickly and through a simple and manageable interface.
|
||||
|
||||
Simplicity
|
||||
==========
|
||||
|
||||
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
|
||||
deployments across disparate datacenters. The topology is a simple
|
||||
server/client model with the needed functionality built into a single set of
|
||||
daemons. While the default configuration will work with little to no
|
||||
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 programmer 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.
|
||||
|
||||
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
|
||||
Python pickles, enabling fast and light network traffic.
|
||||
|
||||
.. _`ZeroMQ`: http://www.zeromq.org/
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
.. _`Apache 2.0 licence`: http://www.apache.org/licenses/LICENSE-2.0.html
|
13
debian/changelog
vendored
13
debian/changelog
vendored
@ -1,3 +1,16 @@
|
||||
salt (0.10.4-2) unstable; urgency=low
|
||||
|
||||
* zmq3 support: b84f593770 86af5f03c3 c933c9e4ff a7e1d58f87 a5cdd8e313 c10bf6702f 2ea8b7e061 75f2a58b4e
|
||||
* HTML doc package: 7f673796e6 422244cd84 d13dbf0fc2 cfc44ee517 8c5675fb88
|
||||
* only run postrm on salt-common purge 5aa00b6bdd, bd2818797c
|
||||
* switch to debian init scripts 6db36a8307
|
||||
* add logrotate support cb9863e264
|
||||
* add systemd support 6f8a728b9d, 502434bccc
|
||||
* add dmidecode+pciutils to recommends 06dab92c56
|
||||
* misc & dependencies cleanup: 8f8d16c07c 7245c80bca bd68bf7a84
|
||||
|
||||
-- Sean Channel <pentabular@gmail.com> Wed, 14 Nov 2012 10:56:16 -0700
|
||||
|
||||
salt (0.10.4-1precise1) precise; urgency=low
|
||||
|
||||
* New upstream version
|
||||
|
4
debian/control
vendored
4
debian/control
vendored
@ -1,7 +1,7 @@
|
||||
Source: salt
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Maintainer: Corey Quinn <corey@sequestered.net>
|
||||
Maintainer: Sean Channel <pentabular@gmail.com>
|
||||
Build-Depends: debhelper,
|
||||
cython,
|
||||
python | python-all | python-dev | python-all-dev,
|
||||
@ -15,8 +15,6 @@ Build-Depends: debhelper,
|
||||
msgpack-python
|
||||
Standards-Version: 3.9.3
|
||||
Homepage: http://saltstack.org
|
||||
#Vcs-Git: git://git.debian.org/collab-maint/salt.git
|
||||
#Vcs-Browser: http://git.debian.org/?p=collab-maint/salt.git;a=summary
|
||||
#X-Python-Version: >= 2.6, <= 2.7
|
||||
|
||||
|
||||
|
11
debian/salt-common.logrotate
vendored
Normal file
11
debian/salt-common.logrotate
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/var/log/salt/master
|
||||
/var/log/salt/minion
|
||||
/var/log/salt/key
|
||||
/var/log/salt/*.log
|
||||
{
|
||||
weekly
|
||||
missingok
|
||||
rotate 7
|
||||
compress
|
||||
notifempty
|
||||
}
|
21
debian/salt-common.postrm
vendored
21
debian/salt-common.postrm
vendored
@ -5,33 +5,14 @@
|
||||
clean_common() {
|
||||
# remove shared job cache and other runtime directories
|
||||
rm -rf /var/cache/salt /var/run/salt /etc/salt /var/log/salt 2> /dev/null
|
||||
}
|
||||
|
||||
clean_conf() {
|
||||
# remove config and log file for master, minion, or syndic
|
||||
rm -f /etc/salt/$1 /var/log/salt/$1 2> /dev/null
|
||||
# XXX add more specific files to purge here XXX #
|
||||
}
|
||||
|
||||
purgefiles() {
|
||||
case "$pkg" in
|
||||
master|minion|syndic)
|
||||
clean_conf $pkg ;;
|
||||
common)
|
||||
clean_common ;;
|
||||
*)
|
||||
echo "$0 unknown package \`$1'" 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
pkg=`echo $0 | cut -f1 -d. | cut -f2 -d-`
|
||||
|
||||
case "$1" in
|
||||
remove)
|
||||
;;
|
||||
purge)
|
||||
purgefiles ;;
|
||||
clean_common ;;
|
||||
upgrade|failed-upgrade|disappear|abort-install|abort-upgrade)
|
||||
;;
|
||||
*)
|
||||
|
191
debian/salt-master.init
vendored
191
debian/salt-master.init
vendored
@ -1,138 +1,99 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Salt master
|
||||
###################################
|
||||
|
||||
# LSB header
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: salt-master
|
||||
# Required-Start: $remote_fs $network
|
||||
# Required-Stop: $remote_fs $network
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Provides: salt-master
|
||||
# Required-Start: $remote_fs $network
|
||||
# Required-Stop: $remote_fs $network
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: salt master control daemon
|
||||
# Description: This is a daemon that controls the salt minions
|
||||
# Description: This is a daemon that controls the salt minions
|
||||
### END INIT INFO
|
||||
|
||||
# chkconfig header
|
||||
# Author: Michael Prokop <mika@debian.org>
|
||||
|
||||
# chkconfig: 2345 99 01
|
||||
# description: This is a daemon that controls the salt mininons
|
||||
#
|
||||
# processname: /usr/bin/salt-master
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="salt master control daemon"
|
||||
NAME=salt-master
|
||||
DAEMON=/usr/bin/salt-master
|
||||
DAEMON_ARGS="-d"
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
# Sanity checks.
|
||||
[ -x /usr/bin/salt-master ] || exit 0
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
DEBIAN_VERSION=/etc/debian_version
|
||||
SUSE_RELEASE=/etc/SuSE-release
|
||||
# Source function library.
|
||||
if [ -f $DEBIAN_VERSION ]; then
|
||||
break
|
||||
elif [ -f $SUSE_RELEASE -a -r /etc/rc.status ]; then
|
||||
. /etc/rc.status
|
||||
else
|
||||
. /etc/rc.d/init.d/functions
|
||||
fi
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||
|
||||
SERVICE=salt-master
|
||||
PROCESS=salt-master
|
||||
CONFIG_ARGS=" "
|
||||
. /lib/init/vars.sh
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
PS_CMD="ps -e -o pid,args"
|
||||
PROC_LIST=""
|
||||
|
||||
RETVAL=0
|
||||
|
||||
findproc() {
|
||||
PROC_LIST=`$PS_CMD | grep 'bin/python.*salt-master' | grep -v grep | grep -v sh | grep -v vi | awk '{ print $1 }'`
|
||||
}
|
||||
|
||||
start() {
|
||||
echo -n "Starting salt-master daemon: "
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
startproc -f -p /var/run/$SERVICE.pid /usr/bin/salt-master -d $CONFIG_ARGS
|
||||
rc_status -v
|
||||
elif [ -e $DEBIAN_VERSION ]; then
|
||||
findproc
|
||||
if [ -n "$PROC_LIST" ]; then
|
||||
echo -n "already started, lock file found"
|
||||
RETVAL=1
|
||||
elif /usr/bin/python /usr/bin/salt-master -d; then
|
||||
echo -n "OK"
|
||||
RETVAL=0
|
||||
fi
|
||||
else
|
||||
daemon --check $SERVICE $PROCESS -d $CONFIG_ARGS
|
||||
do_start() {
|
||||
pid=$(pidofproc -p $PIDFILE $DAEMON)
|
||||
if [ -n "$pid" ] ; then
|
||||
log_begin_msg "$DESC already running."
|
||||
log_end_msg 0
|
||||
exit 0
|
||||
fi
|
||||
RETVAL=$?
|
||||
echo
|
||||
return $RETVAL
|
||||
|
||||
log_daemon_msg "Starting salt-master daemon: "
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS
|
||||
log_end_msg $?
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n "Stopping salt-master daemon: "
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
killproc -TERM /usr/bin/salt-master
|
||||
rc_status -v
|
||||
elif [ -f $DEBIAN_VERSION ]; then
|
||||
# Added this since Debian's start-stop-daemon doesn't support spawned processes
|
||||
findproc
|
||||
if echo $PROC_LIST | xargs kill >/dev/null 2>&1 ; then
|
||||
echo -n "OK"
|
||||
RETVAL=0
|
||||
else
|
||||
echo -n "Daemon is not started"
|
||||
RETVAL=1
|
||||
fi
|
||||
else
|
||||
killproc $PROCESS
|
||||
fi
|
||||
RETVAL=$?
|
||||
echo
|
||||
do_stop() {
|
||||
log_begin_msg "Stopping $DESC ..."
|
||||
start-stop-daemon --stop --retry TERM/5 --quiet --oknodo --pidfile $PIDFILE
|
||||
RC=$?
|
||||
[ $RC -eq 0 ] && rm -f $PIDFILE
|
||||
log_end_msg $RC
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start|stop|restart)
|
||||
$1
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
echo -n "Checking for service salt-master "
|
||||
checkproc /usr/bin/salt-master
|
||||
rc_status -v
|
||||
elif [ -f $DEBIAN_VERSION ]; then
|
||||
findproc
|
||||
if [ -n "$PROC_LIST" ]; then
|
||||
RETVAL=0
|
||||
echo "salt-master is running."
|
||||
else
|
||||
RETVAL=1
|
||||
echo "salt-master is stopped."
|
||||
fi
|
||||
else
|
||||
status $PROCESS
|
||||
RETVAL=$?
|
||||
fi
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
condrestart)
|
||||
findproc
|
||||
[ -n "$PROC_LIST" ] && restart || :
|
||||
;;
|
||||
reload|force-reload)
|
||||
echo "Can't reload configuration, you have to restart it"
|
||||
RETVAL=$?
|
||||
#reload)
|
||||
# not implemented
|
||||
#;;
|
||||
restart|force-reload)
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|restart|condrestart|reload|force-reload}"
|
||||
exit 1
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
exit $RETVAL
|
||||
|
||||
exit 0
|
||||
|
1
debian/salt-master.install
vendored
1
debian/salt-master.install
vendored
@ -4,3 +4,4 @@ scripts/salt-cp /usr/bin
|
||||
scripts/salt-run /usr/bin
|
||||
scripts/salt-key /usr/bin
|
||||
scripts/salt /usr/bin
|
||||
debian/salt-master.service /lib/systemd/system
|
||||
|
42
debian/salt-master.postrm
vendored
42
debian/salt-master.postrm
vendored
@ -1,42 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Purge config files, logs, and directories created after package install.
|
||||
# Note that user-specified alternate locations for these are not affected.
|
||||
|
||||
clean_common() {
|
||||
# remove shared job cache and other runtime directories
|
||||
rm -rf /var/cache/salt /var/run/salt /etc/salt /var/log/salt 2> /dev/null
|
||||
}
|
||||
|
||||
clean_conf() {
|
||||
# remove config and log file for master, minion, or syndic
|
||||
rm -f /etc/salt/$1 /var/log/salt/$1 2> /dev/null
|
||||
# XXX add more specific files to purge here XXX #
|
||||
}
|
||||
|
||||
purgefiles() {
|
||||
case "$pkg" in
|
||||
master|minion|syndic)
|
||||
clean_conf $pkg ;;
|
||||
common)
|
||||
clean_common ;;
|
||||
*)
|
||||
echo "$0 unknown package \`$1'" 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
pkg=`echo $0 | cut -f1 -d. | cut -f2 -d-`
|
||||
|
||||
case "$1" in
|
||||
remove)
|
||||
;;
|
||||
purge)
|
||||
purgefiles ;;
|
||||
upgrade|failed-upgrade|disappear|abort-install|abort-upgrade)
|
||||
;;
|
||||
*)
|
||||
echo "$0 unknown action \`$1'" 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
exit 0
|
10
debian/salt-master.service
vendored
Normal file
10
debian/salt-master.service
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=The Salt Master Server
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/salt-master -d
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
191
debian/salt-minion.init
vendored
191
debian/salt-minion.init
vendored
@ -1,138 +1,99 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Salt minion
|
||||
###################################
|
||||
|
||||
# LSB header
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: salt-minion
|
||||
# Required-Start: $remote_fs $network
|
||||
# Required-Stop: $remote_fs $network
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Provides: salt-minion
|
||||
# Required-Start: $remote_fs $network
|
||||
# Required-Stop: $remote_fs $network
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: salt minion control daemon
|
||||
# Description: This is a daemon that controls the salt minions
|
||||
# Description: This is a daemon that controls the salt minions
|
||||
### END INIT INFO
|
||||
|
||||
# chkconfig header
|
||||
# Author: Michael Prokop <mika@debian.org>
|
||||
|
||||
# chkconfig: 2345 99 01
|
||||
# description: This is a daemon that controls the salt mininons
|
||||
#
|
||||
# processname: /usr/bin/salt-minion
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="salt minion control daemon"
|
||||
NAME=salt-minion
|
||||
DAEMON=/usr/bin/salt-minion
|
||||
DAEMON_ARGS=""
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
# Sanity checks.
|
||||
[ -x /usr/bin/salt-minion ] || exit 0
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
DEBIAN_VERSION=/etc/debian_version
|
||||
SUSE_RELEASE=/etc/SuSE-release
|
||||
# Source function library.
|
||||
if [ -f $DEBIAN_VERSION ]; then
|
||||
break
|
||||
elif [ -f $SUSE_RELEASE -a -r /etc/rc.status ]; then
|
||||
. /etc/rc.status
|
||||
else
|
||||
. /etc/rc.d/init.d/functions
|
||||
fi
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||
|
||||
SERVICE=salt-minion
|
||||
PROCESS=salt-minion
|
||||
CONFIG_ARGS=" "
|
||||
. /lib/init/vars.sh
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
PS_CMD="ps -e -o pid,args"
|
||||
PROC_LIST=""
|
||||
|
||||
RETVAL=0
|
||||
|
||||
findproc() {
|
||||
PROC_LIST=`$PS_CMD | grep 'bin/python.*salt-minion' | grep -v grep | grep -v sh | grep -v vi | awk '{ print $1 }'`
|
||||
}
|
||||
|
||||
start() {
|
||||
echo -n "Starting salt-minion daemon: "
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
startproc -f -p /var/run/$SERVICE.pid /usr/bin/salt-minion -d $CONFIG_ARGS
|
||||
rc_status -v
|
||||
elif [ -e $DEBIAN_VERSION ]; then
|
||||
findproc
|
||||
if [ -n "$PROC_LIST" ]; then
|
||||
echo -n "already started, lock file found"
|
||||
RETVAL=1
|
||||
elif /usr/bin/python /usr/bin/salt-minion -d; then
|
||||
echo -n "OK"
|
||||
RETVAL=0
|
||||
fi
|
||||
else
|
||||
daemon --check $SERVICE $PROCESS -d $CONFIG_ARGS
|
||||
do_start() {
|
||||
pid=$(pidofproc -p $PIDFILE $DAEMON)
|
||||
if [ -n "$pid" ] ; then
|
||||
log_begin_msg "$DESC already running."
|
||||
log_end_msg 0
|
||||
exit 0
|
||||
fi
|
||||
RETVAL=$?
|
||||
echo
|
||||
return $RETVAL
|
||||
|
||||
log_daemon_msg "Starting salt-minion daemon: "
|
||||
start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS
|
||||
log_end_msg $?
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n "Stopping salt-minion daemon: "
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
killproc -TERM /usr/bin/salt-minion
|
||||
rc_status -v
|
||||
elif [ -f $DEBIAN_VERSION ]; then
|
||||
# Added this since Debian's start-stop-daemon doesn't support spawned processes
|
||||
findproc
|
||||
if echo $PROC_LIST | xargs kill >/dev/null 2>&1 ; then
|
||||
echo -n "OK"
|
||||
RETVAL=0
|
||||
else
|
||||
echo -n "Daemon is not started"
|
||||
RETVAL=1
|
||||
fi
|
||||
else
|
||||
killproc $PROCESS
|
||||
fi
|
||||
RETVAL=$?
|
||||
echo
|
||||
do_stop() {
|
||||
log_begin_msg "Stopping $DESC ..."
|
||||
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
|
||||
RC=$?
|
||||
[ $RC -eq 0 ] && rm -f $PIDFILE
|
||||
log_end_msg $RC
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start|stop|restart)
|
||||
$1
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
echo -n "Checking for service salt-minion "
|
||||
checkproc /usr/bin/salt-minion
|
||||
rc_status -v
|
||||
elif [ -f $DEBIAN_VERSION ]; then
|
||||
findproc
|
||||
if [ -n "$PROC_LIST" ]; then
|
||||
RETVAL=0
|
||||
echo "salt-minion is running."
|
||||
else
|
||||
RETVAL=1
|
||||
echo "salt-minion is stopped."
|
||||
fi
|
||||
else
|
||||
status $PROCESS
|
||||
RETVAL=$?
|
||||
fi
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
condrestart)
|
||||
findproc
|
||||
[ -n "$PROC_LIST" ] && restart || :
|
||||
;;
|
||||
reload|force-reload)
|
||||
echo "Can't reload configuration, you have to restart it"
|
||||
RETVAL=$?
|
||||
#reload)
|
||||
# not implemented
|
||||
#;;
|
||||
restart|force-reload)
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|restart|condrestart|reload|force-reload}"
|
||||
exit 1
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
exit $RETVAL
|
||||
|
||||
exit 0
|
||||
|
1
debian/salt-minion.install
vendored
1
debian/salt-minion.install
vendored
@ -1,3 +1,4 @@
|
||||
conf/minion.template /etc/salt
|
||||
scripts/salt-minion /usr/bin
|
||||
scripts/salt-call /usr/bin
|
||||
debian/salt-minion.service /lib/systemd/system
|
||||
|
42
debian/salt-minion.postrm
vendored
42
debian/salt-minion.postrm
vendored
@ -1,42 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Purge config files, logs, and directories created after package install.
|
||||
# Note that user-specified alternate locations for these are not affected.
|
||||
|
||||
clean_common() {
|
||||
# remove shared job cache and other runtime directories
|
||||
rm -rf /var/cache/salt /var/run/salt /etc/salt /var/log/salt 2> /dev/null
|
||||
}
|
||||
|
||||
clean_conf() {
|
||||
# remove config and log file for master, minion, or syndic
|
||||
rm -f /etc/salt/$1 /var/log/salt/$1 2> /dev/null
|
||||
# XXX add more specific files to purge here XXX #
|
||||
}
|
||||
|
||||
purgefiles() {
|
||||
case "$pkg" in
|
||||
master|minion|syndic)
|
||||
clean_conf $pkg ;;
|
||||
common)
|
||||
clean_common ;;
|
||||
*)
|
||||
echo "$0 unknown package \`$1'" 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
pkg=`echo $0 | cut -f1 -d. | cut -f2 -d-`
|
||||
|
||||
case "$1" in
|
||||
remove)
|
||||
;;
|
||||
purge)
|
||||
purgefiles ;;
|
||||
upgrade|failed-upgrade|disappear|abort-install|abort-upgrade)
|
||||
;;
|
||||
*)
|
||||
echo "$0 unknown action \`$1'" 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
exit 0
|
10
debian/salt-minion.service
vendored
Normal file
10
debian/salt-minion.service
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=The Salt Minion
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/salt-minion -d
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
189
debian/salt-syndic.init
vendored
189
debian/salt-syndic.init
vendored
@ -1,134 +1,99 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Salt syndic
|
||||
###################################
|
||||
|
||||
# LSB header
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: salt-syndic
|
||||
# Required-Start: $remote_fs $network
|
||||
# Required-Stop: $remote_fs $network
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: salt syndic master-minion passthrough daemon
|
||||
# Description: This is a daemon that controls the salt syndic
|
||||
# Provides: salt-syndic
|
||||
# Required-Start: $remote_fs $network
|
||||
# Required-Stop: $remote_fs $network
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: salt syndic control daemon
|
||||
# Description: This is a daemon that controls the salt minions
|
||||
### END INIT INFO
|
||||
|
||||
# chkconfig header
|
||||
# Author: Michael Prokop <mika@debian.org>
|
||||
|
||||
# chkconfig: 2345 99 01
|
||||
# description: This is a daemon that controls the salt mininons
|
||||
#
|
||||
# processname: /usr/bin/salt-syndic
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="salt syndic control daemon"
|
||||
NAME=salt-syndic
|
||||
DAEMON=/usr/bin/salt-syndic
|
||||
DAEMON_ARGS="-d"
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
# Sanity checks.
|
||||
[ -x /usr/bin/salt-syndic ] || exit 0
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
DEBIAN_VERSION=/etc/debian_version
|
||||
SUSE_RELEASE=/etc/SuSE-release
|
||||
# Source function library.
|
||||
if [ -f $DEBIAN_VERSION ]; then
|
||||
break
|
||||
elif [ -f $SUSE_RELEASE -a -r /etc/rc.status ]; then
|
||||
. /etc/rc.status
|
||||
else
|
||||
. /etc/rc.d/init.d/functions
|
||||
fi
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||
|
||||
SERVICE=salt-syndic
|
||||
PROCESS=salt-syndic
|
||||
CONFIG_ARGS=" "
|
||||
. /lib/init/vars.sh
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
PS_CMD="ps -e -o pid,args"
|
||||
PROC_LIST=""
|
||||
|
||||
RETVAL=0
|
||||
|
||||
findproc() {
|
||||
PROC_LIST=`$PS_CMD | grep 'bin/python.*salt-syndic' | grep -v grep | grep -v sh | grep -v vi | awk '{ print $1 }'`
|
||||
}
|
||||
|
||||
start() {
|
||||
echo -n "Starting salt-syndic daemon: "
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
startproc -f -p /var/run/$SERVICE.pid /usr/bin/salt-syndic -d $CONFIG_ARGS
|
||||
rc_status -v
|
||||
elif [ -e $DEBIAN_VERSION ]; then
|
||||
findproc
|
||||
if [ -n "$PROC_LIST" ]; then
|
||||
echo -n "already started, lock file found"
|
||||
RETVAL=1
|
||||
elif /usr/bin/python /usr/bin/salt-syndic -d; then
|
||||
echo -n "OK"
|
||||
RETVAL=0
|
||||
fi
|
||||
else
|
||||
daemon --check $SERVICE $PROCESS -d $CONFIG_ARGS
|
||||
do_start() {
|
||||
pid=$(pidofproc -p $PIDFILE $DAEMON)
|
||||
if [ -n "$pid" ] ; then
|
||||
log_begin_msg "$DESC already running."
|
||||
log_end_msg 0
|
||||
exit 0
|
||||
fi
|
||||
RETVAL=$?
|
||||
echo
|
||||
return $RETVAL
|
||||
|
||||
log_daemon_msg "Starting salt-syndic daemon: "
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS
|
||||
log_end_msg $?
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n "Stopping salt-syndic daemon: "
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
killproc -TERM /usr/bin/salt-syndic
|
||||
rc_status -v
|
||||
elif [ -f $DEBIAN_VERSION ]; then
|
||||
# Added this since Debian's start-stop-daemon doesn't support spawned processes
|
||||
findproc
|
||||
if echo $PROC_LIST | xargs kill >/dev/null 2>&1 ; then
|
||||
echo -n "OK"
|
||||
RETVAL=0
|
||||
else
|
||||
echo -n "Daemon is not started"
|
||||
RETVAL=1
|
||||
fi
|
||||
else
|
||||
killproc $PROCESS
|
||||
fi
|
||||
RETVAL=$?
|
||||
echo
|
||||
do_stop() {
|
||||
log_begin_msg "Stopping $DESC ..."
|
||||
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
|
||||
RC=$?
|
||||
[ $RC -eq 0 ] && rm -f $PIDFILE
|
||||
log_end_msg $RC
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start|stop|restart)
|
||||
$1
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
if [ -f $SUSE_RELEASE ]; then
|
||||
echo -n "Checking for service salt-syndic "
|
||||
checkproc /usr/bin/salt-syndic
|
||||
rc_status -v
|
||||
elif [ -f $DEBIAN_VERSION ]; then
|
||||
findproc
|
||||
if [ -n "$PROC_LIST" ]; then
|
||||
RETVAL=0
|
||||
echo "salt-syndic is running."
|
||||
else
|
||||
RETVAL=1
|
||||
echo "salt-syndic is stopped."
|
||||
fi
|
||||
else
|
||||
status $PROCESS
|
||||
RETVAL=$?
|
||||
fi
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
reload|force-reload)
|
||||
echo "Can't reload configuration, you have to restart it"
|
||||
RETVAL=$?
|
||||
#reload)
|
||||
# not implemented
|
||||
#;;
|
||||
restart|force-reload)
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|restart|reload|force-reload}"
|
||||
exit 1
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
exit $RETVAL
|
||||
|
||||
exit 0
|
||||
|
1
debian/salt-syndic.install
vendored
1
debian/salt-syndic.install
vendored
@ -1 +1,2 @@
|
||||
scripts/salt-syndic /usr/bin
|
||||
debian/salt-syndic.service /lib/systemd/system
|
||||
|
41
debian/salt-syndic.postrm
vendored
41
debian/salt-syndic.postrm
vendored
@ -1,41 +0,0 @@
|
||||
# Purge config files, logs, and directories created after package install.
|
||||
# Note that user-specified alternate locations for these are not affected.
|
||||
|
||||
clean_common() {
|
||||
# remove shared job cache and other runtime directories
|
||||
rm -rf /var/cache/salt /var/run/salt /etc/salt /var/log/salt 2> /dev/null
|
||||
}
|
||||
|
||||
clean_conf() {
|
||||
# remove config and log file for master, minion, or syndic
|
||||
rm -f /etc/salt/$1 /var/log/salt/$1 2> /dev/null
|
||||
# XXX add more specific files to purge here XXX #
|
||||
}
|
||||
|
||||
purgefiles() {
|
||||
case "$pkg" in
|
||||
master|minion|syndic)
|
||||
clean_conf $pkg ;;
|
||||
common)
|
||||
clean_common ;;
|
||||
*)
|
||||
echo "$0 unknown package \`$1'" 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
pkg=`echo $0 | cut -f1 -d. | cut -f2 -d-`
|
||||
|
||||
case "$1" in
|
||||
remove)
|
||||
;;
|
||||
purge)
|
||||
purgefiles ;;
|
||||
upgrade|failed-upgrade|disappear|abort-install|abort-upgrade)
|
||||
;;
|
||||
*)
|
||||
echo "$0 unknown action \`$1'" 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
exit 0
|
10
debian/salt-syndic.service
vendored
Normal file
10
debian/salt-syndic.service
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=The Salt Master Server
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/salt-syndic -d
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
2
debian/salt-syndic.upstart
vendored
2
debian/salt-syndic.upstart
vendored
@ -5,7 +5,5 @@ start on (net-device-up
|
||||
and runlevel [2345])
|
||||
stop on runlevel [!2345]
|
||||
|
||||
respawn limit 10 5
|
||||
respawn
|
||||
|
||||
exec /usr/bin/salt-syndic >/dev/null 2>&1
|
||||
|
@ -466,7 +466,7 @@ Default: ``base: [/srv/pillar]``
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
file_roots:
|
||||
pillar_roots:
|
||||
base:
|
||||
- /srv/pillar/
|
||||
dev:
|
||||
|
@ -49,18 +49,43 @@ This example would instruct all Salt minions to download the vimrc from a
|
||||
directory with the same name as their os grain and copy it to /etc/vimrc
|
||||
|
||||
For larger files, the cp.get_file module also supports gzip compression.
|
||||
Because gzip compression is CPU-intensive, this should only be used in
|
||||
Because gzip is CPU-intensive, this should only be used in
|
||||
scenarios where the compression ratio is very high (e.g. pretty-printed JSON
|
||||
or YAML files).
|
||||
|
||||
Use the *gzip_compression* named argument to enable it. Valid values are 1..9,
|
||||
Use the *gzip* named argument to enable it. Valid values are 1..9,
|
||||
where 1 is the lightest compression and 9 the heaviest. 1 uses the least CPU
|
||||
on the master (and minion), 9 uses the most.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt '*' cp.get_file salt://vimrc /etc/vimrc gzip_compression=5
|
||||
# salt '*' cp.get_file salt://vimrc /etc/vimrc gzip=5
|
||||
|
||||
Finally, note that by default cp.get_file does *not* create new destination
|
||||
directories if they do not exist. To change this, use the *makedirs* argument:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt '*' cp.get_file salt://vimrc /etc/vim/vimrc makedirs=True
|
||||
|
||||
In this example, /etc/vim/ would be created if it didn't already exist.
|
||||
|
||||
get_dir
|
||||
```````
|
||||
|
||||
The cp.get_dir function can be used on the minion to download an entire
|
||||
directory from the master. The syntax is very similar to get_file:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt '*' cp.get_dir salt://etc/apache2 /etc
|
||||
|
||||
cp.get_dir supports *template* rendering and *gzip* compression arguments just
|
||||
like get_file:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# salt '*' cp.get_dir salt://etc/{{pillar.webserver}} /etc gzip=5 template=jinja
|
||||
|
||||
|
||||
File Server Client API
|
||||
|
@ -45,18 +45,21 @@ Full list of builtin execution modules
|
||||
freebsdkmod
|
||||
freebsdpkg
|
||||
freebsdservice
|
||||
freebsd_sysctl
|
||||
gem
|
||||
gentoo_service
|
||||
git
|
||||
glance
|
||||
grains
|
||||
groupadd
|
||||
grub
|
||||
hg
|
||||
hosts
|
||||
keystone
|
||||
kmod
|
||||
kvm_hyper
|
||||
launchctl
|
||||
ldap
|
||||
ldapmod
|
||||
linux_sysctl
|
||||
mdadm
|
||||
mongodb
|
||||
@ -66,6 +69,7 @@ Full list of builtin execution modules
|
||||
mysql
|
||||
network
|
||||
nginx
|
||||
nova
|
||||
nzbget
|
||||
openbsdpkg
|
||||
openbsdservice
|
||||
@ -85,6 +89,7 @@ Full list of builtin execution modules
|
||||
pw_user
|
||||
rabbitmq
|
||||
reg
|
||||
ret
|
||||
rh_ip
|
||||
rh_service
|
||||
rvm
|
||||
@ -103,6 +108,7 @@ Full list of builtin execution modules
|
||||
state
|
||||
status
|
||||
supervisord
|
||||
svn
|
||||
systemd
|
||||
test
|
||||
tls
|
||||
@ -119,7 +125,7 @@ Full list of builtin execution modules
|
||||
win_service
|
||||
win_shadow
|
||||
win_useradd
|
||||
yumpkg
|
||||
yumpkg5
|
||||
yumpkg
|
||||
zpool
|
||||
zypper
|
||||
|
6
doc/ref/modules/all/salt.modules.freebsd_sysctl.rst
Normal file
6
doc/ref/modules/all/salt.modules.freebsd_sysctl.rst
Normal file
@ -0,0 +1,6 @@
|
||||
===========================
|
||||
salt.modules.freebsd_sysctl
|
||||
===========================
|
||||
|
||||
.. automodule:: salt.modules.freebsd_sysctl
|
||||
:members:
|
6
doc/ref/modules/all/salt.modules.glance.rst
Normal file
6
doc/ref/modules/all/salt.modules.glance.rst
Normal file
@ -0,0 +1,6 @@
|
||||
===================
|
||||
salt.modules.glance
|
||||
===================
|
||||
|
||||
.. automodule:: salt.modules.glance
|
||||
:members:
|
6
doc/ref/modules/all/salt.modules.keystone.rst
Normal file
6
doc/ref/modules/all/salt.modules.keystone.rst
Normal file
@ -0,0 +1,6 @@
|
||||
=====================
|
||||
salt.modules.keystone
|
||||
=====================
|
||||
|
||||
.. automodule:: salt.modules.keystone
|
||||
:members:
|
@ -1,6 +0,0 @@
|
||||
=================
|
||||
salt.modules.ldap
|
||||
=================
|
||||
|
||||
.. automodule:: salt.modules.ldap
|
||||
:members:
|
6
doc/ref/modules/all/salt.modules.ldapmod.rst
Normal file
6
doc/ref/modules/all/salt.modules.ldapmod.rst
Normal file
@ -0,0 +1,6 @@
|
||||
====================
|
||||
salt.modules.ldapmod
|
||||
====================
|
||||
|
||||
.. automodule:: salt.modules.ldapmod
|
||||
:members:
|
6
doc/ref/modules/all/salt.modules.nova.rst
Normal file
6
doc/ref/modules/all/salt.modules.nova.rst
Normal file
@ -0,0 +1,6 @@
|
||||
=================
|
||||
salt.modules.nova
|
||||
=================
|
||||
|
||||
.. automodule:: salt.modules.nova
|
||||
:members:
|
6
doc/ref/modules/all/salt.modules.ret.rst
Normal file
6
doc/ref/modules/all/salt.modules.ret.rst
Normal file
@ -0,0 +1,6 @@
|
||||
================
|
||||
salt.modules.ret
|
||||
================
|
||||
|
||||
.. automodule:: salt.modules.ret
|
||||
:members:
|
6
doc/ref/modules/all/salt.modules.svn.rst
Normal file
6
doc/ref/modules/all/salt.modules.svn.rst
Normal file
@ -0,0 +1,6 @@
|
||||
================
|
||||
salt.modules.svn
|
||||
================
|
||||
|
||||
.. automodule:: salt.modules.svn
|
||||
:members:
|
@ -10,10 +10,10 @@ Full list of builtin renderer modules
|
||||
:toctree:
|
||||
:template: autosummary.rst.tmpl
|
||||
|
||||
json_jinja
|
||||
json_mako
|
||||
json_wempy
|
||||
yaml_jinja
|
||||
yaml_mako
|
||||
yaml_wempy
|
||||
jinja
|
||||
json
|
||||
mako
|
||||
py
|
||||
stateconf
|
||||
wempy
|
||||
yaml
|
||||
|
6
doc/ref/renderers/all/salt.renderers.jinja.rst
Normal file
6
doc/ref/renderers/all/salt.renderers.jinja.rst
Normal file
@ -0,0 +1,6 @@
|
||||
====================
|
||||
salt.renderers.jinja
|
||||
====================
|
||||
|
||||
.. automodule:: salt.renderers.jinja
|
||||
:members:
|
6
doc/ref/renderers/all/salt.renderers.json.rst
Normal file
6
doc/ref/renderers/all/salt.renderers.json.rst
Normal file
@ -0,0 +1,6 @@
|
||||
===================
|
||||
salt.renderers.json
|
||||
===================
|
||||
|
||||
.. automodule:: salt.renderers.json
|
||||
:members:
|
@ -1,6 +0,0 @@
|
||||
=========================
|
||||
salt.renderers.json_jinja
|
||||
=========================
|
||||
|
||||
.. automodule:: salt.renderers.json_jinja
|
||||
:members:
|
@ -1,6 +0,0 @@
|
||||
========================
|
||||
salt.renderers.json_mako
|
||||
========================
|
||||
|
||||
.. automodule:: salt.renderers.json_mako
|
||||
:members:
|
@ -1,6 +0,0 @@
|
||||
=========================
|
||||
salt.renderers.json_wempy
|
||||
=========================
|
||||
|
||||
.. automodule:: salt.renderers.json_wempy
|
||||
:members:
|
6
doc/ref/renderers/all/salt.renderers.mako.rst
Normal file
6
doc/ref/renderers/all/salt.renderers.mako.rst
Normal file
@ -0,0 +1,6 @@
|
||||
===================
|
||||
salt.renderers.mako
|
||||
===================
|
||||
|
||||
.. automodule:: salt.renderers.mako
|
||||
:members:
|
6
doc/ref/renderers/all/salt.renderers.stateconf.rst
Normal file
6
doc/ref/renderers/all/salt.renderers.stateconf.rst
Normal file
@ -0,0 +1,6 @@
|
||||
========================
|
||||
salt.renderers.stateconf
|
||||
========================
|
||||
|
||||
.. automodule:: salt.renderers.stateconf
|
||||
:members:
|
6
doc/ref/renderers/all/salt.renderers.wempy.rst
Normal file
6
doc/ref/renderers/all/salt.renderers.wempy.rst
Normal file
@ -0,0 +1,6 @@
|
||||
====================
|
||||
salt.renderers.wempy
|
||||
====================
|
||||
|
||||
.. automodule:: salt.renderers.wempy
|
||||
:members:
|
6
doc/ref/renderers/all/salt.renderers.yaml.rst
Normal file
6
doc/ref/renderers/all/salt.renderers.yaml.rst
Normal file
@ -0,0 +1,6 @@
|
||||
===================
|
||||
salt.renderers.yaml
|
||||
===================
|
||||
|
||||
.. automodule:: salt.renderers.yaml
|
||||
:members:
|
@ -1,6 +0,0 @@
|
||||
=========================
|
||||
salt.renderers.yaml_jinja
|
||||
=========================
|
||||
|
||||
.. automodule:: salt.renderers.yaml_jinja
|
||||
:members:
|
@ -1,6 +0,0 @@
|
||||
========================
|
||||
salt.renderers.yaml_mako
|
||||
========================
|
||||
|
||||
.. automodule:: salt.renderers.yaml_mako
|
||||
:members:
|
@ -1,6 +0,0 @@
|
||||
=========================
|
||||
salt.renderers.yaml_wempy
|
||||
=========================
|
||||
|
||||
.. automodule:: salt.renderers.yaml_wempy
|
||||
:members:
|
@ -45,6 +45,39 @@ use the Python or ``py`` renderer:
|
||||
|
||||
The first line is a shebang that references the ``py`` renderer.
|
||||
|
||||
Composing Renderers
|
||||
-------------------
|
||||
A render can be composed from other renderers by connecting them in a series
|
||||
of pipes(``|``). In fact, the default ``Jinja + YAML`` renderer is implemented
|
||||
by combining a yaml renderer and a jinja renderer. Such renderer configuration
|
||||
is specified as: ``jinja | yaml``.
|
||||
|
||||
Other renderer combinations are possible, here's a few examples:
|
||||
|
||||
``yaml``
|
||||
i.e, just YAML, no templating.
|
||||
|
||||
``mako | yaml``
|
||||
pass the input to the ``mako`` renderer, whose output is then fed into the
|
||||
``yaml`` renderer.
|
||||
|
||||
``jinja | mako | yaml``
|
||||
This one allows you to use both jinja and mako templating syntax in the
|
||||
input and then parse the final rendererd output as YAML.
|
||||
|
||||
For backward compatibility, ``jinja | yaml`` can also be written as
|
||||
``yaml_jinja``, and similarly, the ``yaml_mako``, ``yaml_wempy``,
|
||||
``json_jinja``, ``json_mako``, and ``json_wempy`` renderers are all supported
|
||||
as well.
|
||||
|
||||
Keep in mind that not all renderers can be used alone or with any other renderers.
|
||||
For example, the template renderers shouldn't be used alone as their outputs are
|
||||
just strings, which still need to be parsed by another renderer to turn them into
|
||||
highstate data structures. Also, for example, it doesn't make sense to specify
|
||||
``yaml | jinja`` either, because the output of the yaml renderer is a highstate
|
||||
data structure(a dict in Python), which cannot be used as the input to a template
|
||||
renderer. Therefore, when combining renderers, you should know what each renderer
|
||||
accepts as input and what it returns as output.
|
||||
|
||||
Writing Renderers
|
||||
-----------------
|
||||
@ -64,26 +97,13 @@ renderers included with Salt can be found here:
|
||||
|
||||
:blob:`salt/renderers`
|
||||
|
||||
Here is a simple Jinja + YAML example:
|
||||
Here is a simple YAML renderer example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import Python libs
|
||||
import os
|
||||
|
||||
# Import Third Party libs
|
||||
import yaml
|
||||
from jinja2 import Template
|
||||
|
||||
def render(template):
|
||||
'''
|
||||
Render the data passing the functions and grains into the rendering system
|
||||
'''
|
||||
if not os.path.isfile(template):
|
||||
return {}
|
||||
passthrough = {}
|
||||
passthrough.update(__salt__)
|
||||
passthrough.update(__grains__)
|
||||
template = Template(open(template, 'r').read())
|
||||
yaml_data = template.render(**passthrough)
|
||||
return yaml.load(yaml_data)
|
||||
def render(yaml_data, env='', sls='', argline='', **kws):
|
||||
if not isinstance(yaml_data, basestring):
|
||||
yaml_data = yaml_data.read()
|
||||
data = yaml.load(yaml_data)
|
||||
return data if data else {}
|
||||
|
@ -30,16 +30,20 @@ Full list of builtin state modules
|
||||
network
|
||||
pecl
|
||||
pip
|
||||
pkg
|
||||
pkgng
|
||||
pkg
|
||||
postgres_database
|
||||
postgres_user
|
||||
rabbitmq_user
|
||||
rabbitmq_vhost
|
||||
rvm
|
||||
selinux
|
||||
service
|
||||
ssh_auth
|
||||
ssh_known_hosts
|
||||
stateconf
|
||||
supervisord
|
||||
svn
|
||||
sysctl
|
||||
user
|
||||
virtualenv
|
||||
|
6
doc/ref/states/all/salt.states.rabbitmq_user.rst
Normal file
6
doc/ref/states/all/salt.states.rabbitmq_user.rst
Normal file
@ -0,0 +1,6 @@
|
||||
=========================
|
||||
salt.states.rabbitmq_user
|
||||
=========================
|
||||
|
||||
.. automodule:: salt.states.rabbitmq_user
|
||||
:members:
|
6
doc/ref/states/all/salt.states.rabbitmq_vhost.rst
Normal file
6
doc/ref/states/all/salt.states.rabbitmq_vhost.rst
Normal file
@ -0,0 +1,6 @@
|
||||
==========================
|
||||
salt.states.rabbitmq_vhost
|
||||
==========================
|
||||
|
||||
.. automodule:: salt.states.rabbitmq_vhost
|
||||
:members:
|
6
doc/ref/states/all/salt.states.stateconf.rst
Normal file
6
doc/ref/states/all/salt.states.stateconf.rst
Normal file
@ -0,0 +1,6 @@
|
||||
=====================
|
||||
salt.states.stateconf
|
||||
=====================
|
||||
|
||||
.. automodule:: salt.states.stateconf
|
||||
:members:
|
6
doc/ref/states/all/salt.states.svn.rst
Normal file
6
doc/ref/states/all/salt.states.svn.rst
Normal file
@ -0,0 +1,6 @@
|
||||
===============
|
||||
salt.states.svn
|
||||
===============
|
||||
|
||||
.. automodule:: salt.states.svn
|
||||
:members:
|
134
doc/topics/releases/0.10.5.rst
Normal file
134
doc/topics/releases/0.10.5.rst
Normal file
@ -0,0 +1,134 @@
|
||||
=========================
|
||||
Salt 0.10.5 Release Notes
|
||||
=========================
|
||||
|
||||
Salt 0.10.5 is ready, and comes with some great new features. A few more
|
||||
interfaces have been modularized, like the outputter system. The job cache
|
||||
system has been made more powerful and can now use external databases to
|
||||
store and retrive jobs over a long period. The returner system has been
|
||||
extended to allow minions to easily retrive data from a returner interface.
|
||||
|
||||
As usual, this is an exciting release, with many noteworth additions!
|
||||
|
||||
Major Features
|
||||
==============
|
||||
|
||||
External Job Cache
|
||||
------------------
|
||||
|
||||
The external job cache is a system which allows for a returner interface to
|
||||
also act as a job cache. This system is intended to allow users to store
|
||||
job information in a central location for longer periods of time and to make
|
||||
the act of looking up information from jobs executed on other minions easier.
|
||||
|
||||
Currently the external job cache is supported via the mongo and redis
|
||||
returners:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
ext_job_cache: redis
|
||||
redis.host: salt
|
||||
|
||||
Once the external job cache is turned on the new `ret` module can be used on
|
||||
the minions to retrive return information from the job cache. This can be a
|
||||
great way for minions to respond and react to other minions.
|
||||
|
||||
Open Stack Additions
|
||||
--------------------
|
||||
|
||||
Many new additions for openstack integration have been added as Salt marches
|
||||
forward with integrating with Open Stack. The new `nova`, `glance` and
|
||||
`keystone` modules represent the begining of ongoing Open Stack integration.
|
||||
|
||||
The Salt team has had many conversations with core Open Stack developers and
|
||||
is working on linking to Open Stack in powerful new ways.
|
||||
|
||||
Wheel System
|
||||
------------
|
||||
|
||||
A new API was added to the Salt master wich allows the master to be managed
|
||||
via an external API. This new system, allows Salt API to easily hook into the
|
||||
Salt Master and manage configs, modify the state tree, manage the pillar and
|
||||
more. The main motivation for the wheel system is to enable features needed
|
||||
in the upcoming web ui so users can manage the master just as easily as they
|
||||
manage minions.
|
||||
|
||||
The wheel system has also been hooked into the external auth system. This
|
||||
allows specific users to have granular access to manage components of the
|
||||
Salt Master.
|
||||
|
||||
Render Pipes
|
||||
------------
|
||||
|
||||
Jack Kuan has added a substantial new feature. The render pipes system allows
|
||||
Salt to treat the render system like unix pipes. This new system enables sls
|
||||
files to be passed through specific render engines. While the default renderer
|
||||
is still recommended, different engines can be more easily merged. So to pipe
|
||||
the output of mako used in YAML use this shebang line:
|
||||
|
||||
#!mako|yaml
|
||||
|
||||
Salt Key Overhaul
|
||||
-----------------
|
||||
|
||||
The Salt Key system was originally developed as only a cli interface, but as
|
||||
time streched on it was pressed into becoming a clumsy API. This release
|
||||
marks a complete overhaul of Salt Key. Salt Key has been rewritten to funciton
|
||||
purely from an api and to use the outputter system. The benefit here is that
|
||||
the outputter system works much more cleanly with Salt Key now, and the
|
||||
internals of Salt cey can be used much more cleanly.
|
||||
|
||||
Modular Outputters
|
||||
------------------
|
||||
|
||||
The outputter system is now loaded in a modular way. This means that output
|
||||
systems can be more easily added by dropping a python file down on the master
|
||||
that contains the function `output`.
|
||||
|
||||
Unified Module Configuration
|
||||
----------------------------
|
||||
|
||||
In past releases of Salt, the minion configuration files needed to be
|
||||
configured for certian modules to function. This was difficult because
|
||||
it required pre-configuraing the minions. 0.10.5 changes this by making
|
||||
all module configs on minions search the master config file for values.
|
||||
|
||||
Now if a single database server is needed, then it can be defined in the
|
||||
master config and all minions will become aware of the configuration value.
|
||||
|
||||
Salt Call Enhancements
|
||||
----------------------
|
||||
|
||||
The ``salt-call`` command has been updated in a few ways. Now, ``salt-call``
|
||||
can take the --return option to send the data to a returner. Also,
|
||||
``salt-call`` now reports executions in the minion proc system, this
|
||||
allows the master to be aware of the operation salt-call is running.
|
||||
|
||||
Death to pub_refresh and sub_timeout
|
||||
------------------------------------
|
||||
|
||||
The old configuration values `pub_refresh` and `sub_timeout` have been removed.
|
||||
These systems were in place to alleviate problems found in earlier versions of
|
||||
ZeroMQ which have since been fixed, the continued use of these systems has
|
||||
proven to cause problems with message passing and have been completely removed.
|
||||
|
||||
Git Revision Versions
|
||||
---------------------
|
||||
|
||||
When running Salt directly from git (for testing or development, of course)
|
||||
it has been difficult to know exactly what code is being executed. The new
|
||||
versioning system will detect the git revision when building and how many
|
||||
commits have been made since the last release. A release from git will look
|
||||
like this:
|
||||
|
||||
0.10.4-736-gec74d69
|
||||
|
||||
Noteworthy Changes
|
||||
==================
|
||||
|
||||
Arch Linux Defaults to Systemd
|
||||
------------------------------
|
||||
|
||||
Arch Linux recently changed to use systemd by default and discontinued support
|
||||
of init srcipts. Salt has followed suit and defaults to systemd now for
|
||||
manageing services in Arch.
|
@ -28,7 +28,7 @@ Building and Freezing
|
||||
=====================
|
||||
|
||||
Once you have your tools installed and the environment configured, you can then
|
||||
``python setup.py sdist`` to get the eggs prepared. After that is done, run
|
||||
``python setup.py bdist`` to get the eggs prepared. After that is done, run
|
||||
``python setup.py bdist_esky`` to have Esky traverse the module tree and pack
|
||||
all the scripts up into a redistributable. There will be an appropriately
|
||||
versioned ``salt-VERSION.zip`` in ``dist/`` if everything went smoothly.
|
||||
|
@ -6,7 +6,6 @@ Make me some salt!
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
import getpass
|
||||
|
||||
# Import salt libs, the try block bypasses an issue at build time so that
|
||||
# modules don't cause the build to fail
|
||||
|
@ -8,7 +8,6 @@ Required python modules: ldap
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
# Import Salt libs
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
|
@ -4,6 +4,7 @@ minion modules.
|
||||
'''
|
||||
|
||||
# Import python modules
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
import datetime
|
||||
@ -13,6 +14,7 @@ import traceback
|
||||
import salt.loader
|
||||
import salt.minion
|
||||
import salt.output
|
||||
import salt.payload
|
||||
from salt._compat import string_types
|
||||
from salt.log import LOG_LEVELS
|
||||
|
||||
@ -33,6 +35,7 @@ class Caller(object):
|
||||
Pass in the command line options
|
||||
'''
|
||||
self.opts = opts
|
||||
self.serial = salt.payload.Serial(self.opts)
|
||||
# Handle this here so other deeper code which might
|
||||
# be imported as part of the salt api doesn't do a
|
||||
# nasty sys.exit() and tick off our developer users
|
||||
@ -47,13 +50,23 @@ class Caller(object):
|
||||
'''
|
||||
ret = {}
|
||||
fun = self.opts['fun']
|
||||
|
||||
ret['jid'] = '{0:%Y%m%d%H%M%S%f}'.format(datetime.datetime.now())
|
||||
proc_fn = os.path.join(
|
||||
salt.minion.get_proc_dir(self.opts['cachedir']),
|
||||
ret['jid'])
|
||||
if fun not in self.minion.functions:
|
||||
sys.stderr.write('Function {0} is not available\n'.format(fun))
|
||||
sys.exit(1)
|
||||
try:
|
||||
args, kw = salt.minion.detect_kwargs(
|
||||
self.minion.functions[fun], self.opts['arg'])
|
||||
sdata = {
|
||||
'fun': fun,
|
||||
'pid': os.getpid(),
|
||||
'jid': ret['jid'],
|
||||
'tgt': 'salt-call'}
|
||||
with open(proc_fn, 'w+') as fp_:
|
||||
fp_.write(self.serial.dumps(sdata))
|
||||
ret['return'] = self.minion.functions[fun](*args, **kw)
|
||||
except (TypeError, CommandExecutionError) as exc:
|
||||
msg = 'Error running \'{0}\': {1}\n'
|
||||
@ -67,20 +80,22 @@ class Caller(object):
|
||||
msg = 'Command required for \'{0}\' not found: {1}\n'
|
||||
sys.stderr.write(msg.format(fun, str(exc)))
|
||||
sys.exit(1)
|
||||
try:
|
||||
os.remove(proc_fn)
|
||||
except (IOError, OSError):
|
||||
pass
|
||||
if hasattr(self.minion.functions[fun], '__outputter__'):
|
||||
oput = self.minion.functions[fun].__outputter__
|
||||
if isinstance(oput, string_types):
|
||||
ret['out'] = oput
|
||||
if self.opts.get('return', ''):
|
||||
ret['id'] = self.opts['id']
|
||||
ret['jid'] = '{0:%Y%m%d%H%M%S%f}'.format(datetime.datetime.now())
|
||||
ret['fun'] = fun
|
||||
for returner in self.opts['return'].split(','):
|
||||
try:
|
||||
self.minion.returners['{0}.returner'.format(returner)](ret)
|
||||
except Exception as exc:
|
||||
pass
|
||||
|
||||
return ret
|
||||
|
||||
def print_docs(self):
|
||||
|
@ -29,7 +29,6 @@ The data structure needs to be:
|
||||
# This means that the primary client to build is, the LocalClient
|
||||
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
import time
|
||||
import getpass
|
||||
@ -40,6 +39,7 @@ import salt.payload
|
||||
import salt.utils
|
||||
import salt.utils.verify
|
||||
import salt.utils.event
|
||||
import salt.utils.minions
|
||||
from salt.exceptions import SaltInvocationError
|
||||
from salt.exceptions import EauthAuthenticationError
|
||||
|
||||
|
@ -10,7 +10,6 @@ import sys
|
||||
import hmac
|
||||
import hashlib
|
||||
import logging
|
||||
import tempfile
|
||||
|
||||
# Import Cryptography libs
|
||||
from M2Crypto import RSA
|
||||
@ -171,8 +170,7 @@ class Auth(object):
|
||||
'''
|
||||
payload = {}
|
||||
key = self.get_keys()
|
||||
fd_, tmp_pub = tempfile.mkstemp()
|
||||
os.close(fd_)
|
||||
tmp_pub = salt.utils.mkstemp()
|
||||
key.save_pub_key(tmp_pub)
|
||||
payload['enc'] = 'clear'
|
||||
payload['load'] = {}
|
||||
|
@ -96,7 +96,7 @@ class Client(object):
|
||||
yield dest
|
||||
os.umask(cumask)
|
||||
|
||||
def get_file(self, path, dest='', makedirs=False, env='base'):
|
||||
def get_file(self, path, dest='', makedirs=False, env='base', gzip=None):
|
||||
'''
|
||||
Copies a file from the local files or master depending on
|
||||
implementation
|
||||
@ -257,7 +257,7 @@ class Client(object):
|
||||
return dest
|
||||
return False
|
||||
|
||||
def get_dir(self, path, dest='', env='base'):
|
||||
def get_dir(self, path, dest='', env='base', gzip=None):
|
||||
'''
|
||||
Get a directory recursively from the salt-master
|
||||
'''
|
||||
@ -284,7 +284,7 @@ class Client(object):
|
||||
self.get_file(
|
||||
'salt://{0}'.format(fn_),
|
||||
'{0}/{1}'.format(dest, minion_relpath),
|
||||
True, env
|
||||
True, env, gzip
|
||||
)
|
||||
)
|
||||
# Replicate empty dirs from master
|
||||
@ -413,10 +413,10 @@ class LocalClient(Client):
|
||||
return fnd
|
||||
return fnd
|
||||
|
||||
def get_file(self, path, dest='', makedirs=False, env='base', gzip_compression=None):
|
||||
def get_file(self, path, dest='', makedirs=False, env='base', gzip=None):
|
||||
'''
|
||||
Copies a file from the local files directory into :param:`dest`
|
||||
gzip_compression settings are ignored for local files
|
||||
gzip compression settings are ignored for local files
|
||||
'''
|
||||
path = self._check_proto(path)
|
||||
fnd = self._find_file(path, env)
|
||||
@ -555,7 +555,7 @@ class RemoteClient(Client):
|
||||
self.auth = salt.crypt.SAuth(opts)
|
||||
self.sreq = salt.payload.SREQ(self.opts['master_uri'])
|
||||
|
||||
def get_file(self, path, dest='', makedirs=False, env='base', gzip_compression=None):
|
||||
def get_file(self, path, dest='', makedirs=False, env='base', gzip=None):
|
||||
'''
|
||||
Get a single file from the salt-master
|
||||
path must be a salt server location, aka, salt://path/to/file, if
|
||||
@ -567,9 +567,9 @@ class RemoteClient(Client):
|
||||
load = {'path': path,
|
||||
'env': env,
|
||||
'cmd': '_serve_file'}
|
||||
if gzip_compression:
|
||||
gzip_compression = int(gzip_compression)
|
||||
load['gzip_compression'] = gzip_compression
|
||||
if gzip:
|
||||
gzip = int(gzip)
|
||||
load['gzip'] = gzip
|
||||
|
||||
fn_ = None
|
||||
if dest:
|
||||
@ -609,8 +609,7 @@ class RemoteClient(Client):
|
||||
with self._cache_loc(data['dest'], env) as cache_dest:
|
||||
dest = cache_dest
|
||||
fn_ = open(dest, 'wb+')
|
||||
gzip_compression = data.get('gzip_compression', None)
|
||||
if gzip_compression:
|
||||
if data.get('gzip', None):
|
||||
data = salt.utils.gzip_util.uncompress(data['data'])
|
||||
else:
|
||||
data = data['data']
|
||||
|
@ -167,12 +167,13 @@ def _memdata(osdata):
|
||||
meminfo = '/proc/meminfo'
|
||||
|
||||
if os.path.isfile(meminfo):
|
||||
for line in open(meminfo, 'r').readlines():
|
||||
comps = line.split(':')
|
||||
if not len(comps) > 1:
|
||||
continue
|
||||
if comps[0].strip() == 'MemTotal':
|
||||
grains['mem_total'] = int(comps[1].split()[0]) / 1024
|
||||
with open(meminfo, 'r') as f:
|
||||
for line in f:
|
||||
comps = line.rstrip('\n').split(':')
|
||||
if not len(comps) > 1:
|
||||
continue
|
||||
if comps[0].strip() == 'MemTotal':
|
||||
grains['mem_total'] = int(comps[1].split()[0]) / 1024
|
||||
elif osdata['kernel'] in ('FreeBSD', 'OpenBSD'):
|
||||
sysctl = salt.utils.which('sysctl')
|
||||
if sysctl:
|
||||
@ -406,15 +407,15 @@ def id_():
|
||||
'''
|
||||
return {'id': __opts__.get('id', '')}
|
||||
|
||||
_REPLACE_LINUX_RE = re.compile(r'linux', re.IGNORECASE)
|
||||
|
||||
# This maps (at most) the first ten characters (no spaces, lowercased) of
|
||||
# 'osfullname' to the 'os' grain that Salt traditionally uses.
|
||||
# Please see _supported_dists defined at the top of the file
|
||||
_OS_NAME_MAP = {
|
||||
'redhatente': 'RedHat',
|
||||
'debian': 'Debian',
|
||||
'gentoobase': 'Gentoo',
|
||||
'arch': 'Arch',
|
||||
'amazonlinu': 'Amazon',
|
||||
'centoslinu': 'CentOS',
|
||||
'scientific': 'Scientific',
|
||||
}
|
||||
|
||||
# Map the 'os' grain to the 'os_family' grain
|
||||
@ -481,19 +482,20 @@ def os_data():
|
||||
except ImportError:
|
||||
# if the python library isn't available, default to regex
|
||||
if os.path.isfile('/etc/lsb-release'):
|
||||
for line in open('/etc/lsb-release').readlines():
|
||||
# Matches any possible format:
|
||||
# DISTRIB_ID="Ubuntu"
|
||||
# DISTRIB_ID='Mageia'
|
||||
# DISTRIB_ID=Fedora
|
||||
# DISTRIB_RELEASE='10.10'
|
||||
# DISTRIB_CODENAME='squeeze'
|
||||
# DISTRIB_DESCRIPTION='Ubuntu 10.10'
|
||||
regex = re.compile('^(DISTRIB_(?:ID|RELEASE|CODENAME|DESCRIPTION))=(?:\'|")?([\w\s\.-_]+)(?:\'|")?')
|
||||
match = regex.match(line)
|
||||
if match:
|
||||
# Adds: lsb_distrib_{id,release,codename,description}
|
||||
grains['lsb_{0}'.format(match.groups()[0].lower())] = match.groups()[1].rstrip()
|
||||
with open('/etc/lsb-release') as f:
|
||||
for line in f:
|
||||
# Matches any possible format:
|
||||
# DISTRIB_ID="Ubuntu"
|
||||
# DISTRIB_ID='Mageia'
|
||||
# DISTRIB_ID=Fedora
|
||||
# DISTRIB_RELEASE='10.10'
|
||||
# DISTRIB_CODENAME='squeeze'
|
||||
# DISTRIB_DESCRIPTION='Ubuntu 10.10'
|
||||
regex = re.compile('^(DISTRIB_(?:ID|RELEASE|CODENAME|DESCRIPTION))=(?:\'|")?([\w\s\.-_]+)(?:\'|")?')
|
||||
match = regex.match(line.rstrip('\n'))
|
||||
if match:
|
||||
# Adds: lsb_distrib_{id,release,codename,description}
|
||||
grains['lsb_{0}'.format(match.groups()[0].lower())] = match.groups()[1].rstrip()
|
||||
# Use the already intelligent platform module to get distro info
|
||||
(osname, osrelease, oscodename) = platform.linux_distribution(
|
||||
supported_dists=_supported_dists)
|
||||
@ -507,11 +509,12 @@ def os_data():
|
||||
osrelease).strip()
|
||||
grains['oscodename'] = grains.get('lsb_distrib_codename',
|
||||
oscodename).strip()
|
||||
distroname = _REPLACE_LINUX_RE.sub('', grains['osfullname']).strip()
|
||||
# return the first ten characters with no spaces, lowercased
|
||||
shortname = grains['osfullname'].replace(' ', '').lower()[:10]
|
||||
shortname = distroname.replace(' ', '').lower()[:10]
|
||||
# this maps the long names from the /etc/DISTRO-release files to the
|
||||
# traditional short names that Salt has used.
|
||||
grains['os'] = _OS_NAME_MAP.get(shortname, grains['osfullname'])
|
||||
grains['os'] = _OS_NAME_MAP.get(shortname, distroname)
|
||||
grains.update(_linux_cpudata())
|
||||
elif grains['kernel'] == 'SunOS':
|
||||
grains['os'] = 'Solaris'
|
||||
|
@ -16,6 +16,7 @@ import traceback
|
||||
|
||||
# Import Salt libs
|
||||
from salt.exceptions import LoaderError
|
||||
from salt.template import check_render_pipe_str
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
salt_base_path = os.path.dirname(salt.__file__)
|
||||
@ -155,7 +156,7 @@ def render(opts, functions):
|
||||
pack = {'name': '__salt__',
|
||||
'value': functions}
|
||||
rend = load.filter_func('render', pack)
|
||||
if opts['renderer'] not in rend:
|
||||
if not check_render_pipe_str(opts['renderer'], rend):
|
||||
err = ('The renderer {0} is unavailable, this error is often because '
|
||||
'the needed software is unavailable'.format(opts['renderer']))
|
||||
log.critical(err)
|
||||
@ -541,6 +542,8 @@ class Loader(object):
|
||||
for mod in modules:
|
||||
if not hasattr(mod, '__salt__'):
|
||||
mod.__salt__ = funcs
|
||||
elif not pack:
|
||||
mod.__salt__.update(funcs)
|
||||
return funcs
|
||||
|
||||
def _apply_outputter(self, func, mod):
|
||||
|
@ -14,7 +14,6 @@ import shutil
|
||||
import stat
|
||||
import logging
|
||||
import hashlib
|
||||
import tempfile
|
||||
import datetime
|
||||
import pwd
|
||||
import getpass
|
||||
@ -42,6 +41,7 @@ import salt.runner
|
||||
import salt.auth
|
||||
import salt.wheel
|
||||
import salt.minion
|
||||
import salt.utils
|
||||
import salt.utils.atomicfile
|
||||
import salt.utils.event
|
||||
import salt.utils.verify
|
||||
@ -539,8 +539,7 @@ class AESFuncs(object):
|
||||
pub_path = os.path.join(self.opts['pki_dir'], 'minions', id_)
|
||||
with open(pub_path, 'r') as fp_:
|
||||
minion_pub = fp_.read()
|
||||
fd_, tmp_pub = tempfile.mkstemp()
|
||||
os.close(fd_)
|
||||
tmp_pub = salt.utils.mkstemp()
|
||||
with open(tmp_pub, 'w+') as fp_:
|
||||
fp_.write(minion_pub)
|
||||
|
||||
@ -631,14 +630,14 @@ class AESFuncs(object):
|
||||
if not fnd['path']:
|
||||
return ret
|
||||
ret['dest'] = fnd['rel']
|
||||
gzip_compression = load.get('gzip_compression', None)
|
||||
gzip = load.get('gzip', None)
|
||||
|
||||
with open(fnd['path'], 'rb') as fp_:
|
||||
fp_.seek(load['loc'])
|
||||
data = fp_.read(self.opts['file_buffer_size'])
|
||||
if gzip_compression and data:
|
||||
data = salt.utils.gzip_util.compress(data, gzip_compression)
|
||||
ret['gzip_compression'] = gzip_compression
|
||||
if gzip and data:
|
||||
data = salt.utils.gzip_util.compress(data, gzip)
|
||||
ret['gzip'] = gzip
|
||||
ret['data'] = data
|
||||
return ret
|
||||
|
||||
@ -1082,7 +1081,7 @@ class AESFuncs(object):
|
||||
key)
|
||||
try:
|
||||
pub = RSA.load_pub_key(pubfn)
|
||||
except RSA.RSAError, e:
|
||||
except RSA.RSAError:
|
||||
return self.crypticle.dumps({})
|
||||
|
||||
pret = {}
|
||||
|
@ -23,7 +23,7 @@ import zmq
|
||||
# Import salt libs
|
||||
from salt.exceptions import AuthenticationError, \
|
||||
CommandExecutionError, CommandNotFoundError, SaltInvocationError, \
|
||||
SaltClientError, SaltReqTimeoutError
|
||||
SaltReqTimeoutError
|
||||
import salt.client
|
||||
import salt.crypt
|
||||
import salt.loader
|
||||
@ -306,7 +306,8 @@ class Minion(object):
|
||||
fn_ = os.path.join(minion_instance.proc_dir, data['jid'])
|
||||
sdata = {'pid': os.getpid()}
|
||||
sdata.update(data)
|
||||
open(fn_, 'w+').write(minion_instance.serial.dumps(sdata))
|
||||
with open(fn_, 'w+') as fp_:
|
||||
fp_.write(minion_instance.serial.dumps(sdata))
|
||||
ret = {}
|
||||
for ind in range(0, len(data['arg'])):
|
||||
try:
|
||||
@ -639,7 +640,6 @@ class Minion(object):
|
||||
if socket in socks and socks[socket] == zmq.POLLIN:
|
||||
payload = self.serial.loads(socket.recv())
|
||||
self._handle_payload(payload)
|
||||
last = time.time()
|
||||
time.sleep(0.05)
|
||||
multiprocessing.active_children()
|
||||
self.passive_refresh()
|
||||
|
@ -41,12 +41,13 @@ def __parse_aliases():
|
||||
ret = []
|
||||
if not os.path.isfile(afn):
|
||||
return ret
|
||||
for line in open(afn).readlines():
|
||||
m = __ALIAS_RE.match(line)
|
||||
if m:
|
||||
ret.append(m.groups())
|
||||
else:
|
||||
ret.append((None, None, line.strip()))
|
||||
with open(afn, 'r') as f:
|
||||
for line in f:
|
||||
m = __ALIAS_RE.match(line)
|
||||
if m:
|
||||
ret.append(m.groups())
|
||||
else:
|
||||
ret.append((None, None, line.strip()))
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -34,31 +34,25 @@ __outputter__ = {
|
||||
'ring': 'txt',
|
||||
}
|
||||
|
||||
nt = ''
|
||||
host = ''
|
||||
thrift_port = ''
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only load if pycassa is available and the system is configured
|
||||
'''
|
||||
global nt
|
||||
global host
|
||||
global thrift_port
|
||||
|
||||
if not load:
|
||||
return False
|
||||
|
||||
try:
|
||||
nt = __pillar__['cassandra.nodetool']
|
||||
host = __pillar__['cassandra.host']
|
||||
thrift_port = str(__pillar__['cassandra.thrift_port'])
|
||||
except ImportError:
|
||||
#log.info('Module failed to load: pycassa is not installed')
|
||||
return False
|
||||
except KeyError:
|
||||
#log.info('Module failed to load: cassandra.* pillar '
|
||||
# 'values are incomplete')
|
||||
return False
|
||||
nt = __salt__['config.option']('cassandra.nodetool')
|
||||
host = __salt__['config.option']('cassandra.host')
|
||||
thrift_port = str(__salt__['config.option']('cassandra.thrift_port'))
|
||||
|
||||
return 'cassandra'
|
||||
if nt and host and thrift_port:
|
||||
return 'cassandra'
|
||||
return False
|
||||
|
||||
|
||||
def _nodetool(cmd):
|
||||
|
@ -5,12 +5,10 @@ Keep in mind that this module is insecure, in that it can give whomever has
|
||||
access to the master root execution access to all salt minions
|
||||
'''
|
||||
# Import Python libs
|
||||
import pipes
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import sys
|
||||
from functools import partial
|
||||
|
||||
@ -312,8 +310,7 @@ def script(
|
||||
salt '*' cmd.script salt://scripts/runme.sh
|
||||
salt '*' cmd.script salt://scripts/runme.sh 'arg1 arg2 "arg 3"'
|
||||
'''
|
||||
fd_, path = tempfile.mkstemp()
|
||||
os.close(fd_)
|
||||
path = salt.utils.mkstemp()
|
||||
if template:
|
||||
__salt__['cp.get_template'](source, path, template, env, **kwargs)
|
||||
else:
|
||||
@ -410,8 +407,7 @@ def exec_code(lang, code, cwd=None):
|
||||
|
||||
salt '*' cmd.exec_code ruby 'puts "cheese"'
|
||||
'''
|
||||
fd_, codefile = tempfile.mkstemp()
|
||||
os.close(fd_)
|
||||
codefile = salt.utils.mkstemp()
|
||||
with open(codefile, 'w+') as fp_:
|
||||
fp_.write(code)
|
||||
|
||||
|
@ -74,7 +74,7 @@ def valid_fileproto(uri):
|
||||
return False
|
||||
|
||||
|
||||
def option(value):
|
||||
def option(value, default=''):
|
||||
'''
|
||||
Pass in a generic option and recieve the value that will be assigned
|
||||
'''
|
||||
@ -86,7 +86,7 @@ def option(value):
|
||||
return __pillar__[value]
|
||||
elif value in defaults:
|
||||
return defaults[value]
|
||||
return ''
|
||||
return default
|
||||
|
||||
|
||||
def dot_vals(value):
|
||||
|
@ -4,11 +4,11 @@ Minion side functions for salt-cp
|
||||
# Import python libs
|
||||
import os
|
||||
import logging
|
||||
import tempfile
|
||||
|
||||
# Import salt libs
|
||||
import salt.minion
|
||||
import salt.fileclient
|
||||
import salt.utils
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -41,8 +41,47 @@ def recv(files, dest):
|
||||
|
||||
return ret
|
||||
|
||||
def _render_filenames(path, dest, env, template):
|
||||
if not template:
|
||||
return (path, dest)
|
||||
|
||||
def get_file(path, dest, env='base', template=None, gzip_compression=None):
|
||||
# render the path as a template using path_template_engine as the engine
|
||||
if template not in salt.utils.templates.template_registry:
|
||||
raise CommandExecutionError('Attempted to render file paths with unavailable engine '
|
||||
'{0}'.format(template))
|
||||
|
||||
kwargs = {}
|
||||
kwargs['salt'] = __salt__
|
||||
kwargs['pillar'] = __pillar__
|
||||
kwargs['grains'] = __grains__
|
||||
kwargs['opts'] = __opts__
|
||||
kwargs['env'] = env
|
||||
|
||||
def _render(contents):
|
||||
# write out path to temp file
|
||||
tmp_path_fn = salt.utils.mkstemp()
|
||||
with open(tmp_path_fn, 'w+') as fp_:
|
||||
fp_.write(contents)
|
||||
data = salt.utils.templates.template_registry[template](
|
||||
tmp_path_fn,
|
||||
to_str=True,
|
||||
**kwargs
|
||||
)
|
||||
salt.utils.safe_rm(tmp_path_fn)
|
||||
if not data['result']:
|
||||
# Failed to render the template
|
||||
raise CommandExecutionError('Failed to render file path with error: {0}'.format(
|
||||
data['data']
|
||||
))
|
||||
else:
|
||||
return data['data']
|
||||
|
||||
path = _render(path)
|
||||
dest = _render(dest)
|
||||
return (path, dest)
|
||||
|
||||
|
||||
def get_file(path, dest, env='base', makedirs=False, template=None, gzip=None):
|
||||
'''
|
||||
Used to get a single file from the salt master
|
||||
|
||||
@ -50,57 +89,13 @@ def get_file(path, dest, env='base', template=None, gzip_compression=None):
|
||||
|
||||
salt '*' cp.get_file salt://path/to/file /minion/dest
|
||||
'''
|
||||
if template is not None:
|
||||
# render the path as a template using path_template_engine as the engine
|
||||
if template not in salt.utils.templates.template_registry:
|
||||
log.error('Attempted to render file paths with unavailable engine '
|
||||
'{0}'.format(template))
|
||||
return ''
|
||||
|
||||
kwargs = {}
|
||||
kwargs['salt'] = __salt__
|
||||
kwargs['pillar'] = __pillar__
|
||||
kwargs['grains'] = __grains__
|
||||
kwargs['opts'] = __opts__
|
||||
kwargs['env'] = env
|
||||
|
||||
def _render(contents):
|
||||
# write out path to temp file
|
||||
fd_, tmp_path_fn = tempfile.mkstemp()
|
||||
os.close(fd_)
|
||||
with open(tmp_path_fn, 'w+') as fp_:
|
||||
fp_.write(contents)
|
||||
data = salt.utils.templates.template_registry[template](
|
||||
tmp_path_fn,
|
||||
string=True,
|
||||
**kwargs
|
||||
)
|
||||
salt.utils.safe_rm(tmp_path_fn)
|
||||
if not data['result']:
|
||||
# Failed to render the template
|
||||
raise CommandExecutionError('Failed to render file path with error: {0}'.format(
|
||||
data['data']
|
||||
))
|
||||
else:
|
||||
return data['data']
|
||||
|
||||
|
||||
try:
|
||||
path = _render(path)
|
||||
except CommandExecutionError as exc:
|
||||
log.error(str(exc))
|
||||
return ''
|
||||
try:
|
||||
dest = _render(dest)
|
||||
except CommandExecutionError as exc:
|
||||
log.error(str(exc))
|
||||
return ''
|
||||
(path, dest) = _render_filenames(path, dest, env, template)
|
||||
|
||||
if not hash_file(path, env):
|
||||
return ''
|
||||
else:
|
||||
client = salt.fileclient.get_file_client(__opts__)
|
||||
return client.get_file(path, dest, False, env, gzip_compression)
|
||||
return client.get_file(path, dest, makedirs, env, gzip)
|
||||
|
||||
|
||||
def get_template(path, dest, template='jinja', env='base', **kwargs):
|
||||
@ -123,7 +118,7 @@ def get_template(path, dest, template='jinja', env='base', **kwargs):
|
||||
return client.get_template(path, dest, template, False, env, **kwargs)
|
||||
|
||||
|
||||
def get_dir(path, dest, env='base'):
|
||||
def get_dir(path, dest, env='base', template=None, gzip=None):
|
||||
'''
|
||||
Used to recursively copy a directory from the salt master
|
||||
|
||||
@ -131,8 +126,10 @@ def get_dir(path, dest, env='base'):
|
||||
|
||||
salt '*' cp.get_dir salt://path/to/dir/ /minion/dest
|
||||
'''
|
||||
(path, dest) = _render_filenames(path, dest, env, template)
|
||||
|
||||
client = salt.fileclient.get_file_client(__opts__)
|
||||
return client.get_dir(path, dest, env)
|
||||
return client.get_dir(path, dest, env, gzip)
|
||||
|
||||
|
||||
def get_url(path, dest, env='base'):
|
||||
|
@ -2,12 +2,15 @@
|
||||
Work with cron
|
||||
'''
|
||||
|
||||
import tempfile
|
||||
# Import python libs
|
||||
import os
|
||||
|
||||
TAG = '# Lines below here are managed by Salt, do not edit\n'
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
|
||||
TAG = '# Lines below here are managed by Salt, do not edit\n'
|
||||
|
||||
def _render_tab(lst):
|
||||
'''
|
||||
Takes a tab list structure and renders it to a list for applying it to
|
||||
@ -60,9 +63,9 @@ def _get_cron_cmdstr(user, path):
|
||||
command.
|
||||
'''
|
||||
if __grains__['os'] == 'Solaris':
|
||||
return 'su - {0} -c "crontab {1}"'.format(user,path)
|
||||
return 'su - {0} -c "crontab {1}"'.format(user, path)
|
||||
else:
|
||||
return 'crontab -u {0} {1}'.format(user,path)
|
||||
return 'crontab -u {0} {1}'.format(user, path)
|
||||
|
||||
|
||||
def write_cron_file(user, path):
|
||||
@ -76,8 +79,7 @@ def _write_cron_lines(user, lines):
|
||||
'''
|
||||
Takes a list of lines to be committed to a user's crontab and writes it
|
||||
'''
|
||||
fd_, path = tempfile.mkstemp()
|
||||
os.close(fd_)
|
||||
path = salt.utils.mkstemp()
|
||||
with open(path, 'w+') as fp_:
|
||||
fp_.writelines(lines)
|
||||
if __grains__['os'] == 'Solaris' and user != "root":
|
||||
|
@ -1,10 +1,12 @@
|
||||
'''
|
||||
Support for Debconf
|
||||
'''
|
||||
# Import Salt libs
|
||||
# Import Python libs
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils
|
||||
|
||||
|
||||
def _unpack_lines(out):
|
||||
@ -94,11 +96,11 @@ def set(package, question, type, value, *extra):
|
||||
if extra:
|
||||
value = ' '.join((value,) + tuple(extra))
|
||||
|
||||
fd, fname = tempfile.mkstemp(prefix="salt-")
|
||||
fd_, fname = salt.utils.mkstemp(prefix="salt-", close_fd=False)
|
||||
|
||||
line = "{0} {1} {2} {3}".format(package, question, type, value)
|
||||
os.write(fd, line)
|
||||
os.close(fd)
|
||||
os.write(fd_, line)
|
||||
os.close(fd_)
|
||||
|
||||
_set_file(fname)
|
||||
|
||||
|
@ -2,9 +2,13 @@
|
||||
Service support for Debian systems - uses update-rc.d and service to modify the system
|
||||
'''
|
||||
|
||||
# Import Salt libs
|
||||
import glob
|
||||
import re
|
||||
|
||||
# Import Python libs
|
||||
import salt.utils
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
|
@ -12,13 +12,14 @@ import os
|
||||
import re
|
||||
import time
|
||||
import shutil
|
||||
import tempfile
|
||||
import stat
|
||||
import tempfile
|
||||
import sys
|
||||
import getpass
|
||||
import hashlib
|
||||
import difflib
|
||||
import fnmatch
|
||||
import errno
|
||||
try:
|
||||
import grp
|
||||
import pwd
|
||||
@ -26,6 +27,7 @@ except ImportError:
|
||||
pass
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.find
|
||||
from salt.utils.filebuffer import BufferedReader
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
@ -57,6 +59,12 @@ def __clean_tmp(sfn):
|
||||
os.remove(sfn)
|
||||
|
||||
|
||||
def _error(ret, err_msg):
|
||||
ret['result'] = False
|
||||
ret['comment'] = err_msg
|
||||
return ret
|
||||
|
||||
|
||||
def _is_bin(path):
|
||||
'''
|
||||
Return True if a file is a bin, just checks for NULL char, this should be
|
||||
@ -891,8 +899,7 @@ def source_list(source, source_hash, env):
|
||||
source = single_src
|
||||
break
|
||||
elif proto.startswith('http') or proto == 'ftp':
|
||||
fd_, dest = tempfile.mkstemp()
|
||||
os.close(fd_)
|
||||
dest = salt.utils.mkstemp()
|
||||
fn_ = __salt__['cp.get_url'](single_src, dest)
|
||||
os.remove(fn_)
|
||||
if fn_:
|
||||
@ -1520,13 +1527,16 @@ def makedirs_perms(name, user=None, group=None, mode=0755):
|
||||
if head and tail and not path.exists(head):
|
||||
try:
|
||||
makedirs_perms(head, user, group, mode)
|
||||
except OSError, e:
|
||||
except OSError as exc:
|
||||
# be happy if someone already created the path
|
||||
if e.errno != errno.EEXIST:
|
||||
if exc.errno != errno.EEXIST:
|
||||
raise
|
||||
if tail == os.curdir: # xxx/newdir/. exists if xxx/newdir exists
|
||||
return
|
||||
mkdir(name)
|
||||
check_perms(name, None, user, group, int("%o" % mode) if mode else None)
|
||||
|
||||
|
||||
check_perms(
|
||||
name,
|
||||
None,
|
||||
user,
|
||||
group,
|
||||
int('{0}'.format(mode)) if mode else None)
|
||||
|
@ -52,7 +52,8 @@ def show():
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
for line in out:
|
||||
if line.split('.')[0] not in roots:
|
||||
ret[comps[0]] += "{0}\n".format(line)
|
||||
comps = line.split('=')
|
||||
ret[comps[0]] += '{0}\n'.format(line)
|
||||
continue
|
||||
comps = line.split('=')
|
||||
ret[comps[0]] = comps[1]
|
||||
@ -105,27 +106,28 @@ def persist(name, value, config='/etc/sysctl.conf'):
|
||||
edited = False
|
||||
value = str(value)
|
||||
|
||||
for l in open(config, 'r').readlines():
|
||||
if not l.startswith('{0}='.format(name)):
|
||||
nlines.append(l)
|
||||
continue
|
||||
else:
|
||||
k, rest = l.split('=', 1)
|
||||
if rest.startswith('"'):
|
||||
z, v, rest = rest.split('"', 2)
|
||||
elif rest.startswith('\''):
|
||||
z, v, rest = rest.split('\'', 2)
|
||||
with open(config, 'r') as f:
|
||||
for l in f:
|
||||
if not l.startswith('{0}='.format(name)):
|
||||
nlines.append(l)
|
||||
continue
|
||||
else:
|
||||
v = rest.split()[0]
|
||||
rest = rest[len(v):]
|
||||
if v == value:
|
||||
return 'Already set'
|
||||
new_line = _formatfor(k, value, config, rest)
|
||||
nlines.append(new_line)
|
||||
edited = True
|
||||
k, rest = l.split('=', 1)
|
||||
if rest.startswith('"'):
|
||||
z, v, rest = rest.split('"', 2)
|
||||
elif rest.startswith('\''):
|
||||
z, v, rest = rest.split('\'', 2)
|
||||
else:
|
||||
v = rest.split()[0]
|
||||
rest = rest[len(v):]
|
||||
if v == value:
|
||||
return 'Already set'
|
||||
new_line = _formatfor(k, value, config, rest)
|
||||
nlines.append(new_line)
|
||||
edited = True
|
||||
if not edited:
|
||||
nlines.append("{0}\n".format(_formatfor(name, value, config)))
|
||||
open(config, 'w+').writelines(nlines)
|
||||
with open(config, 'w+') as f: f.writelines(nlines)
|
||||
if config != '/boot/loader.conf':
|
||||
assign(name, value)
|
||||
return 'Updated'
|
||||
|
@ -9,7 +9,7 @@ def _check_pkgng():
|
||||
'''
|
||||
Looks to see if pkgng is being used by checking if database exists
|
||||
'''
|
||||
if os.path.isfile('/var/db/pkg/repo.sqlite'):
|
||||
if os.path.isfile('/var/db/pkg/local.sqlite'):
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -54,7 +54,12 @@ def available_version(name):
|
||||
|
||||
salt '*' pkg.available_version <package name>
|
||||
'''
|
||||
pass
|
||||
if _check_pkgng():
|
||||
for line in __salt__['cmd.run']('pkg search -f {0}'.format(name).splitlines()):
|
||||
if line.startswith('Version'):
|
||||
fn, ver = line.split(':', 1)
|
||||
return ver.strip()
|
||||
return ''
|
||||
|
||||
|
||||
def version(name):
|
||||
|
@ -60,16 +60,17 @@ def _switch(name, on, config='/etc/rc.conf', **kwargs):
|
||||
val = "NO"
|
||||
|
||||
if os.path.exists(config):
|
||||
for line in open(config, 'r').readlines():
|
||||
if not line.startswith('{0}_enable='.format(name)):
|
||||
nlines.append(line)
|
||||
continue
|
||||
rest = line[len(line.split()[0]):] # keep comments etc
|
||||
nlines.append('{0}_enable="{1}"{2}'.format(name, val, rest))
|
||||
edited = True
|
||||
with open(config, 'r') as f:
|
||||
for line in f:
|
||||
if not line.startswith('{0}_enable='.format(name)):
|
||||
nlines.append(line)
|
||||
continue
|
||||
rest = line[len(line.split()[0]):] # keep comments etc
|
||||
nlines.append('{0}_enable="{1}"{2}'.format(name, val, rest))
|
||||
edited = True
|
||||
if not edited:
|
||||
nlines.append("{0}_enable=\"{1}\"\n".format(name, val))
|
||||
open(config, 'w+').writelines(nlines)
|
||||
with open(config, 'w') as f: f.writelines(nlines)
|
||||
return True
|
||||
|
||||
|
||||
|
@ -61,7 +61,6 @@ def image_create(**kwargs):
|
||||
glance help image-create
|
||||
'''
|
||||
nt = _auth()
|
||||
ret = {}
|
||||
CREATE_PARAMS = glanceclient.v1.images.CREATE_PARAMS
|
||||
fields = dict(filter(lambda x: x[0] in CREATE_PARAMS, kwargs.items()))
|
||||
|
||||
|
@ -30,18 +30,19 @@ def list_hosts():
|
||||
ret = {}
|
||||
if not os.path.isfile(hfn):
|
||||
return ret
|
||||
for line in open(hfn).readlines():
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
comps = line.split()
|
||||
if comps[0] in ret:
|
||||
# maybe log a warning ?
|
||||
ret[comps[0]].extend(comps[1:])
|
||||
else:
|
||||
ret[comps[0]] = comps[1:]
|
||||
with open(hfn) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
comps = line.split()
|
||||
if comps[0] in ret:
|
||||
# maybe log a warning ?
|
||||
ret[comps[0]].extend(comps[1:])
|
||||
else:
|
||||
ret[comps[0]] = comps[1:]
|
||||
return ret
|
||||
|
||||
|
||||
@ -123,7 +124,7 @@ def set_host(ip, alias):
|
||||
lines[-1] = '{0}\n'.format(lines[-1])
|
||||
line = ip + '\t\t' + alias + '\n'
|
||||
lines.append(line)
|
||||
open(hfn, 'w+').writelines(lines)
|
||||
with open(hfn, 'w+') as f: f.writelines(lines)
|
||||
return True
|
||||
|
||||
|
||||
@ -158,7 +159,7 @@ def rm_host(ip, alias):
|
||||
else:
|
||||
# Only an alias was removed
|
||||
lines[ind] = '{0}\n'.format(newline)
|
||||
open(hfn, 'w+').writelines(lines)
|
||||
with open(hfn, 'w+') as f: f.writelines(lines)
|
||||
return True
|
||||
|
||||
|
||||
@ -199,5 +200,5 @@ def add_host(ip, alias):
|
||||
lines[-1] = '{0}\n'.format(lines[-1])
|
||||
line = ip + '\t\t' + alias + '\n'
|
||||
lines.append(line)
|
||||
open(hfn, 'w+').writelines(lines)
|
||||
with open(hfn, 'w+') as f: f.writelines(lines)
|
||||
return True
|
||||
|
@ -113,7 +113,7 @@ def persist(name, value, config='/etc/sysctl.conf'):
|
||||
# and it seems unnecessary to indent the below for
|
||||
# loop since it is a fairly large block of code.
|
||||
config_data = _fh.readlines()
|
||||
except (IOError, OSError) as exc:
|
||||
except (IOError, OSError):
|
||||
msg = 'Could not read from file: {0}'
|
||||
raise CommandExecutionError(msg.format(config))
|
||||
|
||||
@ -161,7 +161,7 @@ def persist(name, value, config='/etc/sysctl.conf'):
|
||||
try:
|
||||
with open(config, 'w+') as _fh:
|
||||
_fh.writelines(nlines)
|
||||
except (IOError, OSError) as exc:
|
||||
except (IOError, OSError):
|
||||
msg = 'Could not write to file: {0}'
|
||||
raise CommandExecutionError(msg.format(config))
|
||||
|
||||
|
@ -2,10 +2,13 @@
|
||||
Salt module to manage RAID arrays with mdadm
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
import os
|
||||
import logging
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
|
||||
# Set up logger
|
||||
|
@ -78,22 +78,23 @@ def fstab(config='/etc/fstab'):
|
||||
ret = {}
|
||||
if not os.path.isfile(config):
|
||||
return ret
|
||||
for line in open(config).readlines():
|
||||
if line.startswith('#'):
|
||||
# Commented
|
||||
continue
|
||||
if not line.strip():
|
||||
# Blank line
|
||||
continue
|
||||
comps = line.split()
|
||||
if not len(comps) == 6:
|
||||
# Invalid entry
|
||||
continue
|
||||
ret[comps[1]] = {'device': comps[0],
|
||||
'fstype': comps[2],
|
||||
'opts': comps[3].split(','),
|
||||
'dump': comps[4],
|
||||
'pass': comps[5]}
|
||||
with open(config) as f:
|
||||
for line in f:
|
||||
if line.startswith('#'):
|
||||
# Commented
|
||||
continue
|
||||
if not line.strip():
|
||||
# Blank line
|
||||
continue
|
||||
comps = line.split()
|
||||
if not len(comps) == 6:
|
||||
# Invalid entry
|
||||
continue
|
||||
ret[comps[1]] = {'device': comps[0],
|
||||
'fstype': comps[2],
|
||||
'opts': comps[3].split(','),
|
||||
'dump': comps[4],
|
||||
'pass': comps[5]}
|
||||
return ret
|
||||
|
||||
|
||||
@ -168,7 +169,7 @@ def set_fstab(
|
||||
present = False
|
||||
|
||||
if not os.path.isfile(config):
|
||||
raise CommandExecutionError("Bad config file '{0}'".format(config))
|
||||
raise CommandExecutionError('Bad config file "{0}"'.format(config))
|
||||
|
||||
try:
|
||||
with open(config, 'r') as fh:
|
||||
@ -214,8 +215,8 @@ def set_fstab(
|
||||
else:
|
||||
lines.append(line)
|
||||
except (IOError, OSError) as exc:
|
||||
msg = "Couldn't write to {0}: {1}"
|
||||
raise CommandExecutionError(msg.format(conf, str(exc)))
|
||||
msg = 'Couldn\'t write to {0}: {1}'
|
||||
raise CommandExecutionError(msg.format(config, str(exc)))
|
||||
|
||||
if change:
|
||||
try:
|
||||
@ -224,7 +225,7 @@ def set_fstab(
|
||||
fh.writelines(lines)
|
||||
except (IOError, OSError) as exc:
|
||||
msg = 'File not writable {0}'
|
||||
raise CommandExecutionError(msg.format(filename))
|
||||
raise CommandExecutionError(msg.format(config))
|
||||
|
||||
return 'change'
|
||||
|
||||
@ -244,7 +245,7 @@ def set_fstab(
|
||||
fh.writelines(lines)
|
||||
except (IOError, OSError) as exc:
|
||||
msg = 'File not writable {0}'
|
||||
raise CommandExecutionError(msg.format(filename))
|
||||
raise CommandExecutionError(msg.format(config))
|
||||
if present and not change:
|
||||
# The right entry is already here
|
||||
return 'present'
|
||||
|
@ -101,7 +101,9 @@ def connect(**kwargs):
|
||||
if name in kwargs:
|
||||
connargs[key] = kwargs[name]
|
||||
else:
|
||||
connargs[key] = __salt__['config.option']('mysql.{0}'.format(name))
|
||||
val = __salt__['config.option']('mysql.{0}'.format(name), None)
|
||||
if val is not None:
|
||||
connargs[key] = val
|
||||
|
||||
_connarg('host')
|
||||
_connarg('user')
|
||||
|
@ -2,7 +2,6 @@
|
||||
Module for gathering and managing network information
|
||||
'''
|
||||
# Import Python libs
|
||||
import sys
|
||||
import logging
|
||||
|
||||
# Import Salt libs
|
||||
|
@ -4,6 +4,7 @@ A module to wrap pacman calls, since Arch is the best
|
||||
'''
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -36,12 +37,12 @@ def _parse_pkg_meta(path):
|
||||
if result['retcode'] == 0:
|
||||
for line in result['stdout'].splitlines():
|
||||
if not name:
|
||||
m = re.match('^Name\s*:\s*(.+)\s*$',line)
|
||||
m = re.match('^Name\s*:\s*(\S+)',line)
|
||||
if m:
|
||||
name = m.group(1)
|
||||
continue
|
||||
if not version:
|
||||
m = re.match('^Version\s*:\s*(.+)\s*$',line)
|
||||
m = re.match('^Version\s*:\s*(\S+)',line)
|
||||
if m:
|
||||
version = m.group(1)
|
||||
continue
|
||||
@ -154,32 +155,58 @@ def refresh_db():
|
||||
return ret
|
||||
|
||||
|
||||
def install(name, refresh=False, **kwargs):
|
||||
def install(name, refresh=False, source=None, **kwargs):
|
||||
'''
|
||||
Install the passed package, add refresh=True to install with an -Sy
|
||||
|
||||
name
|
||||
Tha name of the package to be installed.
|
||||
|
||||
refresh
|
||||
Whether or not to refresh the package database before installing.
|
||||
Defaults to False.
|
||||
|
||||
source
|
||||
A package file to install.
|
||||
|
||||
Return a dict containing the new package names and versions::
|
||||
|
||||
{'<package>': {'old': '<old-version>',
|
||||
'new': '<new-version>']}
|
||||
'new': '<new-version>']}
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.install <package name>
|
||||
'''
|
||||
|
||||
if 'source' in kwargs:
|
||||
if __salt__['config.valid_fileproto'](kwargs['source']):
|
||||
pkg_file = __salt__['cp.cache_file'](kwargs['source'])
|
||||
if source is not None:
|
||||
if __salt__['config.valid_fileproto'](source):
|
||||
# Cached package from master
|
||||
pkg_file = __salt__['cp.cache_file'](source)
|
||||
pkg_type = 'remote'
|
||||
else:
|
||||
pkg_file = kwargs['source']
|
||||
# Package file local to the minion
|
||||
pkg_file = source
|
||||
pkg_type = 'local'
|
||||
pname,pversion = _parse_pkg_meta(pkg_file)
|
||||
if name != pname:
|
||||
if not pname:
|
||||
cmd = None
|
||||
if pkg_type == 'remote':
|
||||
log.error('Failed to cache {0}. Are you sure this path is '
|
||||
'correct?'.format(source))
|
||||
elif pkg_type == 'local':
|
||||
if not os.path.isfile(source):
|
||||
log.error('Package file {0} not found. Are you sure this '
|
||||
'path is correct?'.format(source))
|
||||
else:
|
||||
log.error('Unable to parse package metadata for '
|
||||
'{0}'.format(source))
|
||||
elif name != pname:
|
||||
log.error('Package file {0} (Name: {1}) does not match the '
|
||||
'specified package name ({2})'.format(kwargs['source'],
|
||||
'specified package name ({2})'.format(source,
|
||||
pname,
|
||||
name))
|
||||
cmd = ''
|
||||
cmd = None
|
||||
else:
|
||||
cmd = 'pacman -U --noprogressbar --noconfirm {0}'.format(pkg_file)
|
||||
else:
|
||||
@ -194,24 +221,24 @@ def install(name, refresh=False, **kwargs):
|
||||
else:
|
||||
cmd = 'pacman -S --noprogressbar --noconfirm {0}'.format(fname)
|
||||
|
||||
old = list_pkgs()
|
||||
if cmd: __salt__['cmd.retcode'](cmd)
|
||||
new = list_pkgs()
|
||||
|
||||
pkgs = {}
|
||||
for npkg in new:
|
||||
if npkg in old:
|
||||
if old[npkg] == new[npkg]:
|
||||
# no change in the package
|
||||
continue
|
||||
if cmd is not None:
|
||||
old = list_pkgs()
|
||||
__salt__['cmd.retcode'](cmd)
|
||||
new = list_pkgs()
|
||||
for npkg in new:
|
||||
if npkg in old:
|
||||
if old[npkg] == new[npkg]:
|
||||
# no change in the package
|
||||
continue
|
||||
else:
|
||||
# the package was here before and the version has changed
|
||||
pkgs[npkg] = {'old': old[npkg],
|
||||
'new': new[npkg]}
|
||||
else:
|
||||
# the package was here before and the version has changed
|
||||
pkgs[npkg] = {'old': old[npkg],
|
||||
# the package is freshly installed
|
||||
pkgs[npkg] = {'old': '',
|
||||
'new': new[npkg]}
|
||||
else:
|
||||
# the package is freshly installed
|
||||
pkgs[npkg] = {'old': '',
|
||||
'new': new[npkg]}
|
||||
return pkgs
|
||||
|
||||
|
||||
|
@ -4,9 +4,9 @@ Install Python packages with pip to either the system or a virtualenv
|
||||
# Import Python libs
|
||||
import os
|
||||
import logging
|
||||
import tempfile
|
||||
import shutil
|
||||
# Import Salt libs
|
||||
import salt.utils
|
||||
from salt._compat import string_types
|
||||
from salt.exceptions import CommandExecutionError, CommandNotFoundError
|
||||
|
||||
@ -177,8 +177,7 @@ def install(pkgs=None,
|
||||
if requirements:
|
||||
if requirements.startswith('salt://'):
|
||||
req = __salt__['cp.cache_file'](requirements)
|
||||
fd_, treq = tempfile.mkstemp()
|
||||
os.close(fd_)
|
||||
treq = salt.utils.mkstemp()
|
||||
shutil.copyfile(req, treq)
|
||||
else:
|
||||
treq = requirements
|
||||
@ -373,8 +372,7 @@ def uninstall(pkgs=None,
|
||||
if requirements:
|
||||
if requirements.startswith('salt://'):
|
||||
req = __salt__['cp.cache_file'](requirements)
|
||||
fd_, treq = tempfile.mkstemp()
|
||||
os.close(fd_)
|
||||
treq = salt.utils.mkstemp()
|
||||
shutil.copyfile(req, treq)
|
||||
cmd = '{cmd} --requirements "{requirements}" '.format(
|
||||
cmd=cmd, requirements=treq or requirements)
|
||||
|
@ -29,7 +29,7 @@ def parse_config(file_name='/usr/local/etc/pkg.conf'):
|
||||
return 'Unable to find {0} on file system'.format(file_name)
|
||||
|
||||
with open(file_name) as f:
|
||||
for line in f.readlines():
|
||||
for line in f:
|
||||
if line.startswith("#") or line.startswith("\n"):
|
||||
pass
|
||||
else:
|
||||
@ -140,7 +140,7 @@ def install(pkg_name):
|
||||
'''
|
||||
|
||||
cmd = 'pkg install -y {0}'.format(pkg_name)
|
||||
return __salt__['cmd.run'](cm)
|
||||
return __salt__['cmd.run'](cmd)
|
||||
|
||||
|
||||
def delete(pkg_name):
|
||||
|
@ -111,7 +111,7 @@ def parse_config(config_file=None):
|
||||
ret = {}
|
||||
if _check_config_exists(config_file):
|
||||
with open(config_file) as f:
|
||||
for line in f.readlines():
|
||||
for line in f:
|
||||
k, y = line.split('=')
|
||||
ret[k] = y
|
||||
return ret
|
||||
|
@ -9,6 +9,7 @@ import hashlib
|
||||
import shutil
|
||||
import signal
|
||||
import logging
|
||||
import fnmatch
|
||||
import sys
|
||||
|
||||
# Import Salt libs
|
||||
@ -25,6 +26,7 @@ except ImportError:
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _sync(form, env=None):
|
||||
'''
|
||||
Sync the given directory in the given environment
|
||||
@ -113,6 +115,7 @@ def _sync(form, env=None):
|
||||
f.write('')
|
||||
return ret
|
||||
|
||||
|
||||
def _listdir_recursively(rootdir):
|
||||
fileList = []
|
||||
for root, subFolders, files in os.walk(rootdir):
|
||||
@ -121,6 +124,7 @@ def _listdir_recursively(rootdir):
|
||||
fileList.append(os.path.join(relpath,file))
|
||||
return fileList
|
||||
|
||||
|
||||
def _list_emptydirs(rootdir):
|
||||
emptydirs = []
|
||||
for root, subFolders, files in os.walk(rootdir):
|
||||
@ -128,6 +132,7 @@ def _list_emptydirs(rootdir):
|
||||
emptydirs.append(root)
|
||||
return emptydirs
|
||||
|
||||
|
||||
def update(version=None):
|
||||
'''
|
||||
Update the salt minion from the url defined in opts['update_url']
|
||||
@ -145,18 +150,18 @@ def update(version=None):
|
||||
salt '*' saltutil.update 0.10.3
|
||||
'''
|
||||
if not has_esky:
|
||||
return "Esky not available as import"
|
||||
if not getattr(sys, "frozen", False):
|
||||
return "Minion is not running an Esky build"
|
||||
if not __opts__['update_url']:
|
||||
return "'update_url' not configured on this minion"
|
||||
return 'Esky not available as import'
|
||||
if not getattr(sys, 'frozen', False):
|
||||
return 'Minion is not running an Esky build'
|
||||
if not __salt__['config.option']('update_url'):
|
||||
return '"update_url" not configured on this minion'
|
||||
app = esky.Esky(sys.executable, __opts__['update_url'])
|
||||
oldversion = __grains__['saltversion']
|
||||
try:
|
||||
if not version:
|
||||
version = app.find_update()
|
||||
if not version:
|
||||
return "No updates available"
|
||||
return 'No updates available'
|
||||
app.fetch_version(version)
|
||||
app.install_version(version)
|
||||
app.cleanup()
|
||||
@ -168,6 +173,7 @@ def update(version=None):
|
||||
return {'comment': 'Updated from {0} to {1}'.format(oldversion, version),
|
||||
'restarted': restarted}
|
||||
|
||||
|
||||
def sync_modules(env=None):
|
||||
'''
|
||||
Sync the modules from the _modules directory on the salt master file
|
||||
@ -274,9 +280,26 @@ def refresh_pillar():
|
||||
return False
|
||||
|
||||
|
||||
def is_running(fun):
|
||||
'''
|
||||
If the named function is running return the data associated with it/them.
|
||||
The argument can be a glob
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' saltutil.is_running state.highstate
|
||||
'''
|
||||
run = running()
|
||||
ret = []
|
||||
for data in run:
|
||||
if fnmatch.fnmatch(data.get('fun', ''), fun):
|
||||
ret.append(data)
|
||||
return ret
|
||||
|
||||
|
||||
def running():
|
||||
'''
|
||||
Return the data on all running processes salt on the minion
|
||||
Return the data on all running salt processes on the minion
|
||||
|
||||
CLI Example::
|
||||
|
||||
@ -291,7 +314,8 @@ def running():
|
||||
return []
|
||||
for fn_ in os.listdir(proc_dir):
|
||||
path = os.path.join(proc_dir, fn_)
|
||||
data = serial.loads(open(path, 'rb').read())
|
||||
with open(path, 'rb') as fp_:
|
||||
data = serial.loads(fp_.read())
|
||||
if not isinstance(data, dict):
|
||||
# Invalid serial object
|
||||
continue
|
||||
|
@ -117,15 +117,17 @@ def set_password(name, password):
|
||||
if not os.path.isfile(s_file):
|
||||
return ret
|
||||
lines = []
|
||||
for line in open(s_file, 'rb').readlines():
|
||||
comps = line.strip().split(':')
|
||||
if not comps[0] == name:
|
||||
lines.append(line)
|
||||
continue
|
||||
comps[1] = password
|
||||
line = ':'.join(comps)
|
||||
lines.append('{0}\n'.format(line))
|
||||
open(s_file, 'w+').writelines(lines)
|
||||
with open(s_file, 'rb') as fp_:
|
||||
for line in fp_:
|
||||
comps = line.strip().split(':')
|
||||
if not comps[0] == name:
|
||||
lines.append(line)
|
||||
continue
|
||||
comps[1] = password
|
||||
line = ':'.join(comps)
|
||||
lines.append('{0}\n'.format(line))
|
||||
with open(s_file, 'w+') as fp_:
|
||||
fp_.writelines(lines)
|
||||
uinfo = info(name)
|
||||
return uinfo['pwd'] == password
|
||||
|
||||
|
@ -101,15 +101,16 @@ def set_password(name, password):
|
||||
if not os.path.isfile(s_file):
|
||||
return ret
|
||||
lines = []
|
||||
for line in open(s_file, 'rb').readlines():
|
||||
comps = line.strip().split(':')
|
||||
if not comps[0] == name:
|
||||
lines.append(line)
|
||||
continue
|
||||
comps[1] = password
|
||||
line = ':'.join(comps)
|
||||
lines.append('{0}\n'.format(line))
|
||||
open(s_file, 'w+').writelines(lines)
|
||||
with open(s_file, 'rb') as f:
|
||||
for line in f:
|
||||
comps = line.strip().split(':')
|
||||
if not comps[0] == name:
|
||||
lines.append(line)
|
||||
continue
|
||||
comps[1] = password
|
||||
line = ':'.join(comps)
|
||||
lines.append('{0}\n'.format(line))
|
||||
with open(s_file, 'w+') as f: f.writelines(lines)
|
||||
uinfo = info(name)
|
||||
return uinfo['pwd'] == password
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
'''
|
||||
Manage users with the useradd command
|
||||
'''
|
||||
|
||||
# Import Python libs
|
||||
try:
|
||||
import grp
|
||||
import pwd
|
||||
@ -10,7 +12,8 @@ except ImportError:
|
||||
import logging
|
||||
from copy import deepcopy
|
||||
|
||||
from salt._compat import string_types, callable
|
||||
# Import Python libs
|
||||
from salt._compat import string_types
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -2,9 +2,11 @@
|
||||
Package support for Solaris
|
||||
'''
|
||||
|
||||
import tempfile
|
||||
# Import python libs
|
||||
import os
|
||||
import shutil
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
|
||||
def __virtual__():
|
||||
@ -104,15 +106,15 @@ def available_version(name):
|
||||
|
||||
salt '*' pkg.available_version <package name>
|
||||
'''
|
||||
return version(name)
|
||||
return version(name)
|
||||
|
||||
|
||||
def install(name, refresh=False, **kwargs):
|
||||
'''
|
||||
Install the passed package. Can install packages from the following
|
||||
sources::
|
||||
|
||||
* Locally (package already exists on the minion
|
||||
|
||||
* Locally (package already exists on the minion
|
||||
* HTTP/HTTPS server
|
||||
* FTP server
|
||||
* Salt master
|
||||
@ -144,11 +146,11 @@ def install(name, refresh=False, **kwargs):
|
||||
passing '-G' to the pkgadd command.) Solaris default when installing a
|
||||
package in the global zone is to install it in all zones. This overrides
|
||||
that and installs the package only in the global.
|
||||
|
||||
|
||||
CLI Example, installing a datastream package only in the global zone::
|
||||
|
||||
salt 'global_zone' pkg.install SMClgcc346 source=/var/spool/pkg/gcc-3.4.6-sol10-sparc-local.pkg current_zone_only=True
|
||||
|
||||
|
||||
salt 'global_zone' pkg.install SMClgcc346 source=/var/spool/pkg/gcc-3.4.6-sol10-sparc-local.pkg current_zone_only=True
|
||||
|
||||
By default salt automatically provides an adminfile, to automate package
|
||||
installation, with these options set:
|
||||
|
||||
@ -191,7 +193,7 @@ def install(name, refresh=False, **kwargs):
|
||||
directly::
|
||||
|
||||
salt '*' pkg.install <package name once installed> source='salt://srv/salt/pkgs/<package filename>' admin_source='salt://srv/salt/pkgs/<adminfile filename>'
|
||||
|
||||
|
||||
CLI Example - Providing your own adminfile when using states::
|
||||
|
||||
<package name once installed>:
|
||||
@ -203,7 +205,10 @@ def install(name, refresh=False, **kwargs):
|
||||
if not 'source' in kwargs:
|
||||
return 'source option required with solaris pkg installs'
|
||||
else:
|
||||
if (kwargs['source']).startswith('salt://') or (kwargs['source']).startswith('http://') or (kwargs['source']).startswith('https://') or (kwargs['source']).startswith('ftp://'):
|
||||
if (kwargs['source']).startswith('salt://') \
|
||||
or (kwargs['source']).startswith('http://') \
|
||||
or (kwargs['source']).startswith('https://') \
|
||||
or (kwargs['source']).startswith('ftp://'):
|
||||
pkgname = __salt__['cp.cache_file'](kwargs['source'])
|
||||
else:
|
||||
pkgname = (kwargs['source'])
|
||||
@ -212,43 +217,43 @@ def install(name, refresh=False, **kwargs):
|
||||
adminfile = __salt__['cp.cache_file'](kwargs['admin_source'])
|
||||
else:
|
||||
# Set the adminfile default variables
|
||||
email=kwargs.get('email', '')
|
||||
instance=kwargs.get('instance', 'quit')
|
||||
partial=kwargs.get('partial', 'nocheck')
|
||||
runlevel=kwargs.get('runlevel', 'nocheck')
|
||||
idepend=kwargs.get('idepend', 'nocheck')
|
||||
rdepend=kwargs.get('rdepend', 'nocheck')
|
||||
space=kwargs.get('space', 'nocheck')
|
||||
setuid=kwargs.get('setuid', 'nocheck')
|
||||
conflict=kwargs.get('conflict', 'nocheck')
|
||||
action=kwargs.get('action', 'nocheck')
|
||||
basedir=kwargs.get('basedir', 'default')
|
||||
email = kwargs.get('email', '')
|
||||
instance = kwargs.get('instance', 'quit')
|
||||
partial = kwargs.get('partial', 'nocheck')
|
||||
runlevel = kwargs.get('runlevel', 'nocheck')
|
||||
idepend = kwargs.get('idepend', 'nocheck')
|
||||
rdepend = kwargs.get('rdepend', 'nocheck')
|
||||
space = kwargs.get('space', 'nocheck')
|
||||
setuid = kwargs.get('setuid', 'nocheck')
|
||||
conflict = kwargs.get('conflict', 'nocheck')
|
||||
action = kwargs.get('action', 'nocheck')
|
||||
basedir = kwargs.get('basedir', 'default')
|
||||
|
||||
# Make tempfile to hold the adminfile contents.
|
||||
fd, adminfile = tempfile.mkstemp(prefix="salt-")
|
||||
|
||||
fd, adminfile = salt.utils.mkstemp(prefix="salt-", close_fd=False)
|
||||
|
||||
# Write to file then close it.
|
||||
os.write(fd, "email=%s\n" % email)
|
||||
os.write(fd, "instance=%s\n" % instance)
|
||||
os.write(fd, "partial=%s\n" % partial)
|
||||
os.write(fd, "runlevel=%s\n" % runlevel)
|
||||
os.write(fd, "idepend=%s\n" % idepend)
|
||||
os.write(fd, "rdepend=%s\n" % rdepend)
|
||||
os.write(fd, "space=%s\n" % space)
|
||||
os.write(fd, "setuid=%s\n" % setuid)
|
||||
os.write(fd, "conflict=%s\n" % conflict)
|
||||
os.write(fd, "action=%s\n" % action)
|
||||
os.write(fd, "basedir=%s\n" % basedir)
|
||||
os.write(fd, 'email={0}\n'.format(email))
|
||||
os.write(fd, 'email={instance={0}\n'.format(instance))
|
||||
os.write(fd, 'email={partial={0}\n'.format(partial))
|
||||
os.write(fd, 'email={runlevel={0}\n'.format(runlevel))
|
||||
os.write(fd, 'email={idepend={0}\n'.format(idepend))
|
||||
os.write(fd, 'email={rdepend={0}\n'.format(rdepend))
|
||||
os.write(fd, 'email={space={0}\n'.format(space))
|
||||
os.write(fd, 'email={setuid={0}\n'.format(setuid))
|
||||
os.write(fd, 'email={conflict={0}\n'.format(conflict))
|
||||
os.write(fd, 'email={action={0}\n'.format(action))
|
||||
os.write(fd, 'email={basedir={0}\n'.format(basedir))
|
||||
os.close(fd)
|
||||
|
||||
# Get a list of the packages before install so we can diff after to see
|
||||
# Get a list of the packages before install so we can diff after to see
|
||||
# what got installed.
|
||||
old = _get_pkgs()
|
||||
|
||||
cmd = '/usr/sbin/pkgadd -n -a {0} '.format(adminfile)
|
||||
|
||||
# Global only?
|
||||
if kwargs.get('current_zone_only') == "True":
|
||||
if kwargs.get('current_zone_only') == 'True':
|
||||
cmd += '-G '
|
||||
|
||||
cmd += '-d {0} \'all\''.format(pkgname)
|
||||
@ -259,7 +264,7 @@ def install(name, refresh=False, **kwargs):
|
||||
# Get a list of the packages again, including newly installed ones.
|
||||
new = _get_pkgs()
|
||||
|
||||
# Remove the temp adminfile
|
||||
# Remove the temp adminfile
|
||||
if not 'admin_source' in kwargs:
|
||||
os.unlink(adminfile)
|
||||
|
||||
@ -304,39 +309,39 @@ def remove(name, **kwargs):
|
||||
|
||||
# Check to see if the package is installed before we proceed
|
||||
if version(name) == '':
|
||||
return ''
|
||||
return ''
|
||||
|
||||
if 'admin_source' in kwargs:
|
||||
adminfile = __salt__['cp.cache_file'](kwargs['admin_source'])
|
||||
else:
|
||||
# Set the adminfile default variables
|
||||
email=kwargs.get('email', '')
|
||||
instance=kwargs.get('instance', 'quit')
|
||||
partial=kwargs.get('partial', 'nocheck')
|
||||
runlevel=kwargs.get('runlevel', 'nocheck')
|
||||
idepend=kwargs.get('idepend', 'nocheck')
|
||||
rdepend=kwargs.get('rdepend', 'nocheck')
|
||||
space=kwargs.get('space', 'nocheck')
|
||||
setuid=kwargs.get('setuid', 'nocheck')
|
||||
conflict=kwargs.get('conflict', 'nocheck')
|
||||
action=kwargs.get('action', 'nocheck')
|
||||
basedir=kwargs.get('basedir', 'default')
|
||||
email = kwargs.get('email', '')
|
||||
instance = kwargs.get('instance', 'quit')
|
||||
partial = kwargs.get('partial', 'nocheck')
|
||||
runlevel = kwargs.get('runlevel', 'nocheck')
|
||||
idepend = kwargs.get('idepend', 'nocheck')
|
||||
rdepend = kwargs.get('rdepend', 'nocheck')
|
||||
space = kwargs.get('space', 'nocheck')
|
||||
setuid = kwargs.get('setuid', 'nocheck')
|
||||
conflict = kwargs.get('conflict', 'nocheck')
|
||||
action = kwargs.get('action', 'nocheck')
|
||||
basedir = kwargs.get('basedir', 'default')
|
||||
|
||||
# Make tempfile to hold the adminfile contents.
|
||||
fd, adminfile = tempfile.mkstemp(prefix="salt-")
|
||||
|
||||
fd, adminfile = salt.utils.mkstemp(prefix="salt-", close_fd=False)
|
||||
|
||||
# Write to file then close it.
|
||||
os.write(fd, "email=%s\n" % email)
|
||||
os.write(fd, "instance=%s\n" % instance)
|
||||
os.write(fd, "partial=%s\n" % partial)
|
||||
os.write(fd, "runlevel=%s\n" % runlevel)
|
||||
os.write(fd, "idepend=%s\n" % idepend)
|
||||
os.write(fd, "rdepend=%s\n" % rdepend)
|
||||
os.write(fd, "space=%s\n" % space)
|
||||
os.write(fd, "setuid=%s\n" % setuid)
|
||||
os.write(fd, "conflict=%s\n" % conflict)
|
||||
os.write(fd, "action=%s\n" % action)
|
||||
os.write(fd, "basedir=%s\n" % basedir)
|
||||
os.write(fd, 'email={0}\n'.format(email))
|
||||
os.write(fd, 'instance={0}\n'.format(instance))
|
||||
os.write(fd, 'partial={0}\n'.format(partial))
|
||||
os.write(fd, 'runlevel={0}\n'.format(runlevel))
|
||||
os.write(fd, 'idepend={0}\n'.format(idepend))
|
||||
os.write(fd, 'rdepend={0}\n'.format(rdepend))
|
||||
os.write(fd, 'space={0}\n'.format(space))
|
||||
os.write(fd, 'setuid={0}\n'.format(setuid))
|
||||
os.write(fd, 'conflict={0}\n'.format(conflict))
|
||||
os.write(fd, 'action={0}\n'.format(action))
|
||||
os.write(fd, 'basedir={0}\n'.format(basedir))
|
||||
os.close(fd)
|
||||
|
||||
# Get a list of the currently installed pkgs.
|
||||
@ -346,14 +351,15 @@ def remove(name, **kwargs):
|
||||
cmd = '/usr/sbin/pkgrm -n -a {0} {1}'.format(adminfile, name)
|
||||
__salt__['cmd.retcode'](cmd)
|
||||
|
||||
# Remove the temp adminfile
|
||||
# Remove the temp adminfile
|
||||
if not 'admin_source' in kwargs:
|
||||
os.unlink(adminfile)
|
||||
|
||||
# Get a list of the packages after the uninstall
|
||||
new = _get_pkgs()
|
||||
|
||||
# Compare the pre and post remove package objects and report the uninstalled pkgs.
|
||||
|
||||
# Compare the pre and post remove package objects and report the
|
||||
# uninstalled pkgs.
|
||||
return _list_removed(old, new)
|
||||
|
||||
|
||||
|
@ -81,7 +81,6 @@ def _replace_auth_key(
|
||||
lines = []
|
||||
uinfo = __salt__['user.info'](user)
|
||||
full = os.path.join(uinfo['home'], config)
|
||||
|
||||
try:
|
||||
# open the file for both reading AND writing
|
||||
with open(full, 'r') as _fh:
|
||||
|
@ -10,6 +10,9 @@ import logging
|
||||
# Import Salt libs
|
||||
import salt.state
|
||||
import salt.payload
|
||||
from salt.utils.yaml import load as yaml_load
|
||||
from salt.utils.yaml import CustomLoader as YamlCustomLoader
|
||||
import json
|
||||
from salt._compat import string_types
|
||||
|
||||
__outputter__ = {
|
||||
@ -22,6 +25,29 @@ __outputter__ = {
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def running():
|
||||
'''
|
||||
Return a dict of state return data if a state function is already running.
|
||||
This function is used to prevent multiple state calls from being run at
|
||||
the same time.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' state.running
|
||||
'''
|
||||
ret = []
|
||||
active = __salt__['saltutil.is_running']('state.*')
|
||||
for data in active:
|
||||
err = ('The function "{0}" is running as PID {1} and was started at '
|
||||
'{2} ').format(
|
||||
data['fun'],
|
||||
data['pid'],
|
||||
salt.utils.jid_to_time(data['jid']),
|
||||
)
|
||||
ret.append(err)
|
||||
return ret
|
||||
|
||||
|
||||
def low(data):
|
||||
'''
|
||||
Execute a single low data call
|
||||
@ -31,6 +57,9 @@ def low(data):
|
||||
|
||||
salt '*' state.low '{"state": "pkg", "fun": "installed", "name": "vi"}'
|
||||
'''
|
||||
conflict = running()
|
||||
if conflict:
|
||||
return conflict
|
||||
st_ = salt.state.State(__opts__)
|
||||
err = st_.verify_data(data)
|
||||
if err:
|
||||
@ -47,6 +76,9 @@ def high(data):
|
||||
|
||||
salt '*' state.high '{"vim": {"pkg": ["installed"]}}'
|
||||
'''
|
||||
conflict = running()
|
||||
if conflict:
|
||||
return conflict
|
||||
st_ = salt.state.State(__opts__)
|
||||
return st_.call_high(data)
|
||||
|
||||
@ -59,6 +91,9 @@ def template(tem):
|
||||
|
||||
salt '*' state.template '<Path to template on the minion>'
|
||||
'''
|
||||
conflict = running()
|
||||
if conflict:
|
||||
return conflict
|
||||
st_ = salt.state.State(__opts__)
|
||||
return st_.call_template(tem)
|
||||
|
||||
@ -71,6 +106,9 @@ def template_str(tem):
|
||||
|
||||
salt '*' state.template_str '<Template String>'
|
||||
'''
|
||||
conflict = running()
|
||||
if conflict:
|
||||
return conflict
|
||||
st_ = salt.state.State(__opts__)
|
||||
return st_.call_template_str(tem)
|
||||
|
||||
@ -83,6 +121,9 @@ def highstate(test=None, **kwargs):
|
||||
|
||||
salt '*' state.highstate
|
||||
'''
|
||||
conflict = running()
|
||||
if conflict:
|
||||
return conflict
|
||||
salt.utils.daemonize_if(__opts__, **kwargs)
|
||||
opts = copy.copy(__opts__)
|
||||
|
||||
@ -99,8 +140,8 @@ def highstate(test=None, **kwargs):
|
||||
try:
|
||||
with open(cache_file, 'w+') as fp_:
|
||||
serial.dump(ret, fp_)
|
||||
except (IOError, OSError) as exc:
|
||||
msg = "Unable to write to 'state.highstate' cache file {0}"
|
||||
except (IOError, OSError):
|
||||
msg = 'Unable to write to "state.highstate" cache file {0}'
|
||||
log.error(msg.format(cache_file))
|
||||
|
||||
return ret
|
||||
@ -115,6 +156,9 @@ def sls(mods, env='base', test=None, **kwargs):
|
||||
|
||||
salt '*' state.sls core,edit.vim dev
|
||||
'''
|
||||
conflict = running()
|
||||
if conflict:
|
||||
return conflict
|
||||
opts = copy.copy(__opts__)
|
||||
|
||||
if not test is None:
|
||||
@ -137,8 +181,8 @@ def sls(mods, env='base', test=None, **kwargs):
|
||||
try:
|
||||
with open(cache_file, 'w+') as fp_:
|
||||
serial.dump(ret, fp_)
|
||||
except (IOError, OSError) as exc:
|
||||
msg = "Unable to write to 'state.sls' cache file {0}"
|
||||
except (IOError, OSError):
|
||||
msg = 'Unable to write to "state.sls" cache file {0}'
|
||||
log.error(msg.format(cache_file))
|
||||
return ret
|
||||
|
||||
@ -151,6 +195,9 @@ def top(topfn):
|
||||
|
||||
salt '*' state.top reverse_top.sls
|
||||
'''
|
||||
conflict = running()
|
||||
if conflict:
|
||||
return conflict
|
||||
st_ = salt.state.HighState(__opts__)
|
||||
st_.opts['state_top'] = os.path.join('salt://', topfn)
|
||||
return st_.call_highstate()
|
||||
@ -215,15 +262,24 @@ def show_masterstate():
|
||||
return st_.compile_master()
|
||||
|
||||
|
||||
def single(fun, name, test=None, **kwargs):
|
||||
def single(fun, name, test=None, kwval_as='yaml', **kwargs):
|
||||
'''
|
||||
Execute a single state function with the named kwargs, returns False if
|
||||
insufficient data is sent to the command
|
||||
|
||||
By default, the values of the kwargs will be parsed as YAML. So, you can
|
||||
specify lists values, or lists of single entry key-value maps, as you
|
||||
would in a YAML salt file. Alternatively, JSON format of keyword values
|
||||
is also supported.
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' state.single pkg.installed name=vim
|
||||
|
||||
'''
|
||||
conflict = running()
|
||||
if conflict:
|
||||
return conflict
|
||||
comps = fun.split('.')
|
||||
if len(comps) < 2:
|
||||
return 'Invalid function passed'
|
||||
@ -238,5 +294,20 @@ def single(fun, name, test=None, **kwargs):
|
||||
err = st_.verify_data(kwargs)
|
||||
if err:
|
||||
return err
|
||||
|
||||
if kwval_as == 'yaml':
|
||||
def parse_kwval(value):
|
||||
return yaml_load(value, YamlCustomLoader)
|
||||
elif kwval_as == 'json':
|
||||
def parse_kwval(value):
|
||||
return json.loads(value)
|
||||
else:
|
||||
return 'Unknown format({0}) for state keyword arguments!'.format(
|
||||
kwval_as)
|
||||
|
||||
for key, value in kwargs.iteritems():
|
||||
if not key.startswith('__pub_'):
|
||||
kwargs[key] = parse_kwval(value)
|
||||
|
||||
return {'{0[state]}_|-{0[__id__]}_|-{0[name]}_|-{0[fun]}'.format(kwargs):
|
||||
st_.call(kwargs)}
|
||||
|
@ -650,7 +650,7 @@ def create_pkcs12(ca_name, CN, passphrase=''):
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
create_ca('koji', days=365, **cert_sample_meta)
|
||||
#create_ca('koji', days=365, **cert_sample_meta)
|
||||
create_csr(
|
||||
'koji',
|
||||
CN='test_system',
|
||||
|
@ -2,8 +2,9 @@
|
||||
Module for gathering and managing network information
|
||||
'''
|
||||
|
||||
import sys
|
||||
from string import ascii_letters, digits
|
||||
# Import Salt libs
|
||||
import re
|
||||
# Import Salt libs
|
||||
from salt.utils.socket_util import sanitize_host
|
||||
|
||||
__outputter__ = {
|
||||
@ -170,7 +171,6 @@ def _interfaces_ipconfig(out):
|
||||
Returns a dictionary of interfaces with various information about each
|
||||
(up/down state, ip address, netmask, and hwaddr)
|
||||
'''
|
||||
import re
|
||||
ifaces = dict()
|
||||
iface = None
|
||||
|
||||
|
@ -12,6 +12,7 @@ except (ImportError, AttributeError):
|
||||
has_yumdeps = False
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -105,17 +106,17 @@ def _parse_pkg_meta(path):
|
||||
if result['retcode'] == 0:
|
||||
for line in result['stdout'].splitlines():
|
||||
if not name:
|
||||
m = re.match('^Name\s*:\s*(.+)\s*$', line)
|
||||
m = re.match('^Name\s*:\s*(\S+)', line)
|
||||
if m:
|
||||
name = m.group(1)
|
||||
continue
|
||||
if not version:
|
||||
m = re.match('^Version\s*:\s*(.+)\s*$', line)
|
||||
m = re.match('^Version\s*:\s*(\S+)', line)
|
||||
if m:
|
||||
version = m.group(1)
|
||||
continue
|
||||
if not rel:
|
||||
m = re.match('^Release\s*:\s*(.+)\s*$', line)
|
||||
m = re.match('^Release\s*:\s*(\S+)', line)
|
||||
if m:
|
||||
version = m.group(1)
|
||||
continue
|
||||
@ -300,21 +301,26 @@ def install(pkgs, refresh=False, repo='', skip_verify=False, sources=None,
|
||||
Install the passed package(s)
|
||||
|
||||
pkgs
|
||||
The name of the package(s) to be installed
|
||||
refresh : False
|
||||
Clean out the yum database before executing
|
||||
repo : (default)
|
||||
Specify a package repository to install from
|
||||
The name of the package(s) to be installed. Can be comma separated, or
|
||||
space separated if the parameter is encased in quotes.
|
||||
|
||||
refresh
|
||||
Clean out the yum database before executing. Defaults to False.
|
||||
|
||||
repo
|
||||
Specify a package repository to install from.
|
||||
(e.g., ``yum --enablerepo=somerepo``)
|
||||
skip_verify : False
|
||||
Skip the GPG verification check (e.g., ``--nogpgcheck``)
|
||||
sources: None
|
||||
A list of rpm sources to use for installing these packages.
|
||||
|
||||
skip_verify
|
||||
Skip the GPG verification check. (e.g., ``--nogpgcheck``)
|
||||
|
||||
sources
|
||||
A list of rpm sources to use for installing the package(s).
|
||||
|
||||
Return a dict containing the new package names and versions::
|
||||
|
||||
{'<package>': {'old': '<old-version>',
|
||||
'new': '<new-version>']}
|
||||
'new': '<new-version>']}
|
||||
|
||||
CLI Example::
|
||||
|
||||
@ -328,7 +334,7 @@ def install(pkgs, refresh=False, repo='', skip_verify=False, sources=None,
|
||||
else:
|
||||
pkgs = pkgs.split(' ')
|
||||
|
||||
if sources:
|
||||
if sources is not None:
|
||||
if ',' in sources:
|
||||
srcsplit = sources.split(',')
|
||||
else:
|
||||
@ -341,20 +347,43 @@ def install(pkgs, refresh=False, repo='', skip_verify=False, sources=None,
|
||||
'({1})'.format(len(srcsplit), len(pkgs)))
|
||||
return {}
|
||||
|
||||
sources = [
|
||||
__salt__['cp.cache_file'](x)
|
||||
if __salt__['config.valid_fileproto'](x) else x
|
||||
for x in srcsplit
|
||||
]
|
||||
srcinfo = []
|
||||
for src in srcsplit:
|
||||
if __salt__['config.valid_fileproto'](src):
|
||||
# Cached RPM from master
|
||||
srcinfo.append((__salt__['cp.cache_file'](src),'remote'))
|
||||
else:
|
||||
# RPM file local to the minion
|
||||
srcinfo.append((src,'local'))
|
||||
|
||||
# Check metadata to make sure the name passed matches the source
|
||||
problems = []
|
||||
for i in range(0, len(pkgs)):
|
||||
pname, pversion = _parse_pkg_meta(sources[i])
|
||||
if pkgs[i] != pname:
|
||||
log.error('Package file {0} (Name: {1}) does not '
|
||||
'match the specified package name '
|
||||
'({2})'.format(sources[i], pname, pkgs[i]))
|
||||
return {}
|
||||
rpm_path, pkg_type = srcinfo[i]
|
||||
pname, pversion = _parse_pkg_meta(rpm_path)
|
||||
if not pname:
|
||||
if pkg_type == 'remote':
|
||||
problems.append('Failed to cache {0}. Are you sure this '
|
||||
'path is correct?'.format(srcsplit[i]))
|
||||
elif pkg_type == 'local':
|
||||
if not os.path.isfile(rpm_path):
|
||||
problems.append('Package file {0} not found. Are '
|
||||
'you sure this path is '
|
||||
'correct?'.format(rpm_path))
|
||||
else:
|
||||
problems.append('Unable to parse package metadata for '
|
||||
'{0}'.format(rpm_path))
|
||||
elif pkgs[i] != pname:
|
||||
problems.append('Package file {0} (Name: {1}) does not '
|
||||
'match the specified package name '
|
||||
'({2})'.format(srcsplit[i], pname, pkgs[i]))
|
||||
|
||||
# If any problems are found in the caching or metadata parsing done in
|
||||
# the above for loop, log each problem and then return an empty dict.
|
||||
# Do not proceed to attempt package installation.
|
||||
if problems:
|
||||
for problem in problems: log.error(problem)
|
||||
return {}
|
||||
|
||||
old = list_pkgs(*pkgs)
|
||||
|
||||
@ -369,16 +398,16 @@ def install(pkgs, refresh=False, repo='', skip_verify=False, sources=None,
|
||||
for i in range(0, len(pkgs)):
|
||||
try:
|
||||
if sources is not None:
|
||||
target = sources[i]
|
||||
rpm_path, pkg_type = srcinfo[i]
|
||||
log.info(
|
||||
'Selecting \'{0}\' for local installation'.format(target)
|
||||
'Selecting \'{0}\' for local installation'.format(rpm_path)
|
||||
)
|
||||
a = yb.installLocal(target)
|
||||
a = yb.installLocal(rpm_path)
|
||||
# if yum didn't install anything, maybe its a downgrade?
|
||||
log.debug('Added {0} transactions'.format(len(a)))
|
||||
if len(a) == 0 and target not in old.keys():
|
||||
if len(a) == 0 and rpm_path not in old.keys():
|
||||
log.info('Upgrade failed, trying local downgrade')
|
||||
a = yb.downgradeLocal(target)
|
||||
a = yb.downgradeLocal(rpm_path)
|
||||
else:
|
||||
target = pkgs[i]
|
||||
log.info('Selecting \'{0}\' for installation'.format(target))
|
||||
|
@ -1,8 +1,10 @@
|
||||
'''
|
||||
Support for YUM
|
||||
'''
|
||||
import re
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
@ -13,9 +15,12 @@ def __virtual__():
|
||||
Confine this module to yum based systems
|
||||
'''
|
||||
# Work only on RHEL/Fedora based distros with python 2.6 or greater
|
||||
os_grain = __grains__['os']
|
||||
os_family = __grains__['os_family']
|
||||
os_major_version = int(__grains__['osrelease'].split('.')[0])
|
||||
try:
|
||||
os_grain = __grains__['os']
|
||||
os_family = __grains__['os_family']
|
||||
os_major_version = int(__grains__['osrelease'].split('.')[0])
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
# Fedora <= 10 need to use this module
|
||||
if os_grain == 'Fedora' and os_major_version < 11:
|
||||
@ -72,17 +77,17 @@ def _parse_pkg_meta(path):
|
||||
# with -qpi. So, regexes should not look for EOL after capture
|
||||
# group.
|
||||
if not name:
|
||||
m = re.match('^Name\s*:\s*(\S+)\s*',line)
|
||||
m = re.match('^Name\s*:\s*(\S+)',line)
|
||||
if m:
|
||||
name = m.group(1)
|
||||
continue
|
||||
if not version:
|
||||
m = re.match('^Version\s*:\s*(\S+)\s*',line)
|
||||
m = re.match('^Version\s*:\s*(\S+)',line)
|
||||
if m:
|
||||
version = m.group(1)
|
||||
continue
|
||||
if not rel:
|
||||
m = re.match('^Release\s*:\s*(\S+)\s*',line)
|
||||
m = re.match('^Release\s*:\s*(\S+)',line)
|
||||
if m:
|
||||
version = m.group(1)
|
||||
continue
|
||||
@ -168,46 +173,69 @@ def refresh_db():
|
||||
return True
|
||||
|
||||
|
||||
def install(name, refresh=False, repo='', skip_verify=False, **kwargs):
|
||||
def install(name, refresh=False, repo='', skip_verify=False, source=None,
|
||||
**kwargs):
|
||||
'''
|
||||
Install the passed package
|
||||
|
||||
name
|
||||
The name of the package to be installed
|
||||
refresh : False
|
||||
|
||||
refresh
|
||||
Clean out the yum database before executing
|
||||
repo : (default)
|
||||
Specify a package repository to install from
|
||||
|
||||
repo
|
||||
Specify a package repository from which to install the package
|
||||
(e.g., ``yum --enablerepo=somerepo``)
|
||||
skip_verify : False
|
||||
|
||||
skip_verify
|
||||
Skip the GPG verification check (e.g., ``--nogpgcheck``)
|
||||
|
||||
Return a dict containing the new package names and versions::
|
||||
|
||||
{'<package>': {'old': '<old-version>',
|
||||
'new': '<new-version>']}
|
||||
'new': '<new-version>']}
|
||||
|
||||
CLI Example::
|
||||
|
||||
salt '*' pkg.install <package name>
|
||||
'''
|
||||
if 'source' in kwargs:
|
||||
if __salt__['config.valid_fileproto'](kwargs['source']):
|
||||
pkg_file = __salt__['cp.cache_file'](kwargs['source'])
|
||||
|
||||
if source is not None:
|
||||
if __salt__['config.valid_fileproto'](source):
|
||||
# Cached RPM from master
|
||||
pkg_file = __salt__['cp.cache_file'](source)
|
||||
pkg_type = 'remote'
|
||||
else:
|
||||
pkg_file = kwargs['source']
|
||||
# RPM file local to the minion
|
||||
pkg_file = source
|
||||
pkg_type = 'local'
|
||||
pname,pversion = _parse_pkg_meta(pkg_file)
|
||||
if name != pname:
|
||||
if not pname:
|
||||
pkg_file = None
|
||||
if pkg_type == 'remote':
|
||||
log.error('Failed to cache {0}. Are you sure this path is '
|
||||
'correct?'.format(source))
|
||||
elif pkg_type == 'local':
|
||||
if not os.path.isfile(source):
|
||||
log.error('Package file {0} not found. Are you sure this '
|
||||
'path is correct?'.format(source))
|
||||
else:
|
||||
log.error('Unable to parse package metadata for '
|
||||
'{0}'.format(source))
|
||||
elif name != pname:
|
||||
pkg_file = None
|
||||
log.error('Package file {0} (Name: {1}) does not match the '
|
||||
'specified package name ({2})'.format(kwargs['source'],
|
||||
'specified package name ({2})'.format(source,
|
||||
pname,
|
||||
name))
|
||||
return {}
|
||||
# Don't proceed if there was a problem with the package file
|
||||
if pkg_file is None: return {}
|
||||
|
||||
cmd = 'yum -y {repo} {gpgcheck} install {pkg}'.format(
|
||||
repo='--enablerepo={0}'.format(repo) if repo else '',
|
||||
gpgcheck='--nogpgcheck' if skip_verify else '',
|
||||
pkg=pkg_file if pkg_file is not None else name,
|
||||
pkg=pkg_file if source is not None else name,
|
||||
)
|
||||
|
||||
if refresh: refresh_db()
|
||||
|
@ -4,8 +4,9 @@ in a raw state. This was the original outputter used by Salt before the
|
||||
outputter system was developed.
|
||||
'''
|
||||
|
||||
def ouput(data):
|
||||
|
||||
def output(data):
|
||||
'''
|
||||
Rather basic....
|
||||
'''
|
||||
return data
|
||||
return str(data)
|
||||
|
@ -11,9 +11,13 @@ import os
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
# Import Salt libs
|
||||
from salt.exceptions import SaltInvocationError
|
||||
|
||||
# Import third party libs
|
||||
import yaml
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
try:
|
||||
import ldap
|
||||
import ldap.modlist
|
||||
|
28
salt/renderers/jinja.py
Normal file
28
salt/renderers/jinja.py
Normal file
@ -0,0 +1,28 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt libs
|
||||
from salt.exceptions import SaltRenderError
|
||||
import salt.utils.templates
|
||||
|
||||
|
||||
|
||||
def render(template_file, env='', sls='', context=None, **kws):
|
||||
'''
|
||||
Render the template_file, passing the functions and grains into the
|
||||
Jinja rendering system.
|
||||
|
||||
:rtype: string
|
||||
'''
|
||||
tmp_data = salt.utils.templates.jinja(template_file, to_str=True,
|
||||
salt=__salt__,
|
||||
grains=__grains__,
|
||||
opts=__opts__,
|
||||
pillar=__pillar__,
|
||||
env=env,
|
||||
sls=sls,
|
||||
context=context)
|
||||
if not tmp_data.get('result', False):
|
||||
raise SaltRenderError(tmp_data.get('data',
|
||||
'Unknown render error in jinja renderer'))
|
||||
return tmp_data['data']
|
||||
|
19
salt/renderers/json.py
Normal file
19
salt/renderers/json.py
Normal file
@ -0,0 +1,19 @@
|
||||
from __future__ import absolute_import
|
||||
import json
|
||||
|
||||
def render(json_data, env='', sls='', **kws):
|
||||
'''
|
||||
Accepts JSON as a string or as a file object and runs it through the JSON
|
||||
parser.
|
||||
|
||||
:rtype: A Python data structure
|
||||
'''
|
||||
if not isinstance(json_data, basestring):
|
||||
json_data = json_data.read()
|
||||
|
||||
if json_data.startswith('#!'):
|
||||
json_data = json_data[json_data.find('\n')+1:]
|
||||
if not json_data.strip():
|
||||
return {}
|
||||
return json.loads(json_data)
|
||||
|
@ -1,36 +0,0 @@
|
||||
'''
|
||||
Process json with the jinja2 templating engine
|
||||
|
||||
This renderer will take a json file with the jinja template and render it to a
|
||||
high data format for salt states.
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
import json
|
||||
import os
|
||||
|
||||
# Import salt libs
|
||||
from salt.exceptions import SaltRenderError
|
||||
import salt.utils.templates
|
||||
|
||||
|
||||
def render(template_file, env='', sls=''):
|
||||
'''
|
||||
Render the data passing the functions and grains into the rendering system
|
||||
'''
|
||||
if not os.path.isfile(template_file):
|
||||
return {}
|
||||
|
||||
tmp_data = salt.utils.templates.jinja(
|
||||
template_file,
|
||||
True,
|
||||
salt=__salt__,
|
||||
grains=__grains__,
|
||||
opts=__opts__,
|
||||
pillar=__pillar__,
|
||||
env=env,
|
||||
sls=sls)
|
||||
if not tmp_data.get('result', False):
|
||||
raise SaltRenderError(tmp_data.get('data',
|
||||
'Unknown render error in json_jinja renderer'))
|
||||
return json.loads(tmp_data['data'])
|
@ -1,43 +0,0 @@
|
||||
'''
|
||||
Process json with the Mako templating engine
|
||||
|
||||
This renderer will take a json file with the Mako template and render it to a
|
||||
high data format for salt states.
|
||||
'''
|
||||
# Import python libs
|
||||
import json
|
||||
import os
|
||||
|
||||
# Import salt modules
|
||||
from salt.exceptions import SaltRenderError
|
||||
import salt.utils.templates
|
||||
|
||||
|
||||
def render(template_file, env='', sls=''):
|
||||
'''
|
||||
Render the data passing the functions and grains into the rendering system
|
||||
'''
|
||||
if not os.path.isfile(template_file):
|
||||
return {}
|
||||
|
||||
tmp_data = salt.utils.templates.mako(
|
||||
template_file,
|
||||
True,
|
||||
salt=__salt__,
|
||||
grains=__grains__,
|
||||
opts=__opts__,
|
||||
pillar=__pillar__,
|
||||
env=env,
|
||||
sls=sls)
|
||||
if not tmp_data.get('result', False):
|
||||
raise SaltRenderError(tmp_data.get('data',
|
||||
'Unknown render error in json_mako renderer'))
|
||||
|
||||
# Ensure that we're not passing lines with a shebang in the JSON.
|
||||
to_return = []
|
||||
for line in tmp_data['data'].splitlines():
|
||||
if line and "#!" not in line:
|
||||
to_return.append(line)
|
||||
to_return = '\n'.join(to_return)
|
||||
|
||||
return json.loads(to_return)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user