Merge branch 'develop' of github.com:saltstack/salt into random-module-updates

Conflicts:
	salt/modules/ssh.py
This commit is contained in:
Jeff Schroeder 2012-11-14 20:07:12 -08:00
commit 58d0dd4ce6
136 changed files with 2975 additions and 1615 deletions

81
debian/README.rst vendored
View File

@ -1,81 +0,0 @@
=============
What is Salt?
=============
.. rubric:: Were 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. Salts 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
View File

@ -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
View File

@ -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
View 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
}

View File

@ -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)
;;
*)

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View File

@ -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

View File

@ -1 +1,2 @@
scripts/salt-syndic /usr/bin
debian/salt-syndic.service /lib/systemd/system

View File

@ -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
View 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

View File

@ -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

View File

@ -466,7 +466,7 @@ Default: ``base: [/srv/pillar]``
.. code-block:: yaml
file_roots:
pillar_roots:
base:
- /srv/pillar/
dev:

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,6 @@
===========================
salt.modules.freebsd_sysctl
===========================
.. automodule:: salt.modules.freebsd_sysctl
:members:

View File

@ -0,0 +1,6 @@
===================
salt.modules.glance
===================
.. automodule:: salt.modules.glance
:members:

View File

@ -0,0 +1,6 @@
=====================
salt.modules.keystone
=====================
.. automodule:: salt.modules.keystone
:members:

View File

@ -1,6 +0,0 @@
=================
salt.modules.ldap
=================
.. automodule:: salt.modules.ldap
:members:

View File

@ -0,0 +1,6 @@
====================
salt.modules.ldapmod
====================
.. automodule:: salt.modules.ldapmod
:members:

View File

@ -0,0 +1,6 @@
=================
salt.modules.nova
=================
.. automodule:: salt.modules.nova
:members:

View File

@ -0,0 +1,6 @@
================
salt.modules.ret
================
.. automodule:: salt.modules.ret
:members:

View File

@ -0,0 +1,6 @@
================
salt.modules.svn
================
.. automodule:: salt.modules.svn
:members:

View File

@ -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

View File

@ -0,0 +1,6 @@
====================
salt.renderers.jinja
====================
.. automodule:: salt.renderers.jinja
:members:

View File

@ -0,0 +1,6 @@
===================
salt.renderers.json
===================
.. automodule:: salt.renderers.json
:members:

View File

@ -1,6 +0,0 @@
=========================
salt.renderers.json_jinja
=========================
.. automodule:: salt.renderers.json_jinja
:members:

View File

@ -1,6 +0,0 @@
========================
salt.renderers.json_mako
========================
.. automodule:: salt.renderers.json_mako
:members:

View File

@ -1,6 +0,0 @@
=========================
salt.renderers.json_wempy
=========================
.. automodule:: salt.renderers.json_wempy
:members:

View File

@ -0,0 +1,6 @@
===================
salt.renderers.mako
===================
.. automodule:: salt.renderers.mako
:members:

View File

@ -0,0 +1,6 @@
========================
salt.renderers.stateconf
========================
.. automodule:: salt.renderers.stateconf
:members:

View File

@ -0,0 +1,6 @@
====================
salt.renderers.wempy
====================
.. automodule:: salt.renderers.wempy
:members:

View File

@ -0,0 +1,6 @@
===================
salt.renderers.yaml
===================
.. automodule:: salt.renderers.yaml
:members:

View File

@ -1,6 +0,0 @@
=========================
salt.renderers.yaml_jinja
=========================
.. automodule:: salt.renderers.yaml_jinja
:members:

View File

@ -1,6 +0,0 @@
========================
salt.renderers.yaml_mako
========================
.. automodule:: salt.renderers.yaml_mako
:members:

View File

@ -1,6 +0,0 @@
=========================
salt.renderers.yaml_wempy
=========================
.. automodule:: salt.renderers.yaml_wempy
:members:

View File

@ -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 {}

View File

@ -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

View File

@ -0,0 +1,6 @@
=========================
salt.states.rabbitmq_user
=========================
.. automodule:: salt.states.rabbitmq_user
:members:

View File

@ -0,0 +1,6 @@
==========================
salt.states.rabbitmq_vhost
==========================
.. automodule:: salt.states.rabbitmq_vhost
:members:

View File

@ -0,0 +1,6 @@
=====================
salt.states.stateconf
=====================
.. automodule:: salt.states.stateconf
:members:

View File

@ -0,0 +1,6 @@
===============
salt.states.svn
===============
.. automodule:: salt.states.svn
:members:

View 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.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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'] = {}

View File

@ -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']

View File

@ -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'

View File

@ -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):

View File

@ -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 = {}

View File

@ -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()

View File

@ -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

View File

@ -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):

View File

@ -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)

View File

@ -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):

View File

@ -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'):

View File

@ -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":

View File

@ -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)

View File

@ -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__():
'''

View File

@ -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)

View File

@ -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'

View File

@ -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):

View File

@ -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

View File

@ -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()))

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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'

View File

@ -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')

View File

@ -2,7 +2,6 @@
Module for gathering and managing network information
'''
# Import Python libs
import sys
import logging
# Import Salt libs

View File

@ -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

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__)

View File

@ -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)

View File

@ -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:

View File

@ -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)}

View File

@ -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',

View File

@ -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

View File

@ -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))

View File

@ -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()

View File

@ -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)

View File

@ -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
View 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
View 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)

View File

@ -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'])

View File

@ -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