Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch '0.9.4'

  • Loading branch information...
commit bc2f98ae989b5042c86cf66b14e5a64bfbb33dd8 2 parents 7c86d93 + 12401d6
Thomas S Hatch thatch45 authored
Showing with 5,082 additions and 1,610 deletions.
  1. +6 −6 README.rst
  2. +4 −0 conf/master
  3. +24 −0 debian/changelog
  4. +1 −1  debian/compat
  5. +7 −5 debian/control
  6. +1 −1  debian/files
  7. +3 −3 debian/patches/no-license
  8. +15 −4 debian/salt.salt-master.init
  9. +15 −4 debian/salt.salt-minion.init
  10. +13 −3 debian/salt.salt-syndic.init
  11. +17 −0 doc/_templates/404.html
  12. +4 −1 doc/conf.py
  13. +0 −11 doc/example/templates/json-jinja.json
  14. +0 −11 doc/example/templates/json-mako.json
  15. +0 −12 doc/example/templates/json.json
  16. +0 −23 doc/example/templates/yaml-jinja.yml
  17. +0 −23 doc/example/templates/yaml-mako.yml
  18. +0 −27 doc/example/templates/yaml.yml
  19. +4 −4 doc/home.rst
  20. +1 −1  doc/man/salt-call.1
  21. +1 −1  doc/man/salt-cp.1
  22. +1 −1  doc/man/salt-key.1
  23. +1 −1  doc/man/salt-master.1
  24. +1 −1  doc/man/salt-minion.1
  25. +1 −1  doc/man/salt-run.1
  26. +1 −1  doc/man/salt-syndic.1
  27. +1 −1  doc/man/salt.1
  28. +3,119 −847 doc/man/salt.7
  29. +18 −18 doc/ref/file_server/index.rst
  30. +4 −1 doc/ref/modules/all/index.rst
  31. +6 −0 doc/ref/modules/all/salt.modules.archive.rst
  32. +6 −0 doc/ref/modules/all/salt.modules.ebuild.rst
  33. +6 −0 doc/ref/modules/all/salt.modules.tomcat.rst
  34. +0 −6 doc/ref/modules/all/salt.modules.yum.rst
  35. +11 −0 doc/ref/modules/all/salt.modules.yumpkg.rst
  36. +1 −1  doc/ref/modules/index.rst
  37. +55 −0 doc/ref/states/failhard.rst
  38. +23 −9 doc/ref/states/highstate.rst
  39. +44 −0 doc/ref/states/ordering.rst
  40. +56 −51 doc/topics/installation.rst
  41. +146 −0 doc/topics/releases/0.9.4.rst
  42. +1 −1  doc/topics/tutorials/states_pt1.rst
  43. +20 −11 doc/topics/tutorials/states_pt2.rst
  44. +4 −3 pkg/arch/PKGBUILD
  45. +3 −2 pkg/arch/PKGBUILD-git
  46. +1 −1  salt/__init__.py
  47. +3 −2 salt/cli/__init__.py
  48. +2 −0  salt/config.py
  49. +27 −1 salt/grains/core.py
  50. +3 −3 salt/loader.py
  51. +10 −13 salt/master.py
  52. +22 −31 salt/modules/apt.py
  53. +219 −0 salt/modules/ebuild.py
  54. +1 −0  salt/modules/network.py
  55. +9 −5 salt/modules/publish.py
  56. +1 −1  salt/modules/pw_group.py
  57. +3 −1 salt/modules/pw_user.py
  58. +1 −0  salt/modules/service.py
  59. +2 −3 salt/modules/shadow.py
  60. +609 −199 salt/modules/solr.py
  61. +40 −9 salt/modules/status.py
  62. +3 −1 salt/modules/useradd.py
  63. +0 −198 salt/modules/yum.py
  64. +261 −0 salt/modules/yumpkg.py
  65. +177 −9 salt/state.py
  66. +9 −7 salt/states/cron.py
  67. +19 −4 salt/states/file.py
  68. +14 −8 salt/states/user.py
  69. +1 −17 setup.py
12 README.rst
View
@@ -4,7 +4,7 @@ What is Salt?
.. rubric:: We’re not just talking about NaCl.
-Distributed remote execution
+Distributed Remote Execution
============================
Salt is a distributed remote execution system used to execute commands and
@@ -26,7 +26,7 @@ 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
+Parallel Execution
==================
The core function of Salt is to enable remote commands to be called in parallel
@@ -36,7 +36,7 @@ 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
+Building on Proven Technology
=============================
Salt takes advantage of a number of technologies and techniques. The networking
@@ -49,7 +49,7 @@ Python pickles, enabling fast and light network traffic.
.. _`ZeroMQ`: http://www.zeromq.org/
-Python client interface
+Python Client Interface
=======================
In order to allow for simple expansion, Salt execution routines can be written
@@ -59,8 +59,8 @@ 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, pretty, secure
-========================================
+Fast, Flexible, Scalable, Secure
+================================
The result is a system that can execute commands across groups of
varying size, from very few to very many servers at considerably high
4 conf/master
View
@@ -50,6 +50,10 @@
#
# The renderer to use on the minions to render the state data
#renderer: yaml_jinja
+#
+# The failhard option tells the minions to stop immediately after the first
+# failure detected in the state execution, defaults to False
+#failhard: False
##### File Server settings #####
##########################################
24 debian/changelog
View
@@ -1,3 +1,27 @@
+salt (0.9.4-1) lucid; urgency=low
+
+ * Build PPA for 0.9.4
+
+ -- Seth House <seth@eseth.com> Sun, 27 Nov 2011 16:11:36 -0700
+
+salt (0.9.4.pre-d353743-1) lucid; urgency=low
+
+ * Build PPA for Ubuntu (fixed?)
+
+ -- Seth House <seth@eseth.com> Wed, 25 Nov 2011 23:19:00 -0600
+
+salt (0.9.4.pre-6dd76f2-1) lucid; urgency=low
+
+ * Build PPA for Ubuntu (fixed?)
+
+ -- Seth House <seth@eseth.com> Wed, 25 Nov 2011 11:19:00 -0600
+
+salt (0.9.4.pre-1) lucid; urgency=low
+
+ * Build PPA for Ubuntu
+
+ -- Seth House <seth@eseth.com> Wed, 25 Nov 2011 11:19:00 -0600
+
salt (0.9.2-2) unstable; urgency=low
* Fixed many lintian(1) warnings and errors
2  debian/compat
View
@@ -1 +1 @@
-8
+7
12 debian/control
View
@@ -2,9 +2,11 @@ Source: salt
Section: admin
Priority: optional
Maintainer: Aaron Toponce <aaron.toponce@gmail.com>
-Build-Depends: debhelper (>= 8.0.0), python-support,
- cython
-Standards-Version: 3.9.2
+Build-Depends: debhelper (>= 7), python-support, cython, python-yaml,
+ python-setuptools, python-yaml, python-crypto, python-m2crypto,
+ python-pyzmq (>= 2.1.9), libzmq1 (>= 2.1.9), libzmq-dev (>= 2.1.9),
+ python (>= 2.6), python-jinja2
+Standards-Version: 3.8.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
@@ -12,8 +14,8 @@ Homepage: http://saltstack.org
Package: salt
Architecture: all
Depends: ${python:Depends}, ${misc:Depends}, python-setuptools,
- python-yaml, python-crypto, python-m2crypto, python-zmq, libzmq1,
- libzmq-dev, python (>= 2.6)
+ python-yaml, python-crypto, python-m2crypto, python-pyzmq (>= 2.1.9),
+ libzmq1 (>= 2.1.9), libzmq-dev (>= 2.1.9), python (>= 2.6), python-jinja2
Description: This package provides a remote manager to administer servers.
This package is a powerful remote execution manager that can be used to
administer servers in a fast and efficient way.
2  debian/files
View
@@ -1 +1 @@
-salt_0.9.2-2_all.deb admin optional
+salt_0.9.4-1_all.deb admin optional
6 debian/patches/no-license
View
@@ -1,7 +1,7 @@
-Index: salt-0.9.2/setup.py
+Index: salt-0.9.4/setup.py
===================================================================
---- salt-0.9.2.orig/setup.py 2011-10-03 21:07:32.524520895 -0600
-+++ salt-0.9.2/setup.py 2011-10-03 21:14:33.852854281 -0600
+--- salt-0.9.4.orig/setup.py 2011-10-03 21:07:32.524520895 -0600
++++ salt-0.9.4/setup.py 2011-10-03 21:14:33.852854281 -0600
@@ -92,7 +92,7 @@
['salt/modules/cytest.pyx',
]),
19 debian/salt.salt-master.init
View
@@ -40,15 +40,23 @@ SERVICE=salt-master
PROCESS=salt-master
CONFIG_ARGS=" "
+PS_CMD="ps -e -o pid,args"
+PROC_LIST=""
+
RETVAL=0
+findproc() {
+ PROC_LIST=`$PS_CMD | grep $PROCESS | 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
- if [ -f $LOCKFILE ]; 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
@@ -70,7 +78,8 @@ stop() {
rc_status -v
elif [ -f $DEBIAN_VERSION ]; then
# Added this since Debian's start-stop-daemon doesn't support spawned processes
- if ps -ef | grep "/usr/bin/python /usr/bin/salt-master" | grep -v grep | awk '{print $2}' | xargs kill &> /dev/null; then
+ findproc
+ if echo $PROC_LIST | xargs kill >/dev/null 2>&1 ; then
echo -n "OK"
RETVAL=0
else
@@ -100,7 +109,8 @@ case "$1" in
checkproc /usr/bin/salt-master
rc_status -v
elif [ -f $DEBIAN_VERSION ]; then
- if [ -f $LOCKFILE ]; then
+ findproc
+ if [ -n "$PROC_LIST" ]; then
RETVAL=0
echo "salt-master is running."
else
@@ -113,7 +123,8 @@ case "$1" in
fi
;;
condrestart)
- [ -f $LOCKFILE ] && restart || :
+ findproc
+ [ -n "$PROC_LIST" ] && restart || :
;;
reload|force-reload)
echo "Can't reload configuration, you have to restart it"
19 debian/salt.salt-minion.init
View
@@ -40,15 +40,23 @@ SERVICE=salt-minion
PROCESS=salt-minion
CONFIG_ARGS=" "
+PS_CMD="ps -e -o pid,args"
+PROC_LIST=""
+
RETVAL=0
+findproc() {
+ PROC_LIST=`$PS_CMD | grep $PROCESS | 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
- if [ -f $LOCKFILE ]; 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
@@ -70,7 +78,8 @@ stop() {
rc_status -v
elif [ -f $DEBIAN_VERSION ]; then
# Added this since Debian's start-stop-daemon doesn't support spawned processes
- if ps -ef | grep "/usr/bin/python /usr/bin/salt-minion" | grep -v grep | awk '{print $2}' | xargs kill &> /dev/null; then
+ findproc
+ if echo $PROC_LIST | xargs kill >/dev/null 2>&1 ; then
echo -n "OK"
RETVAL=0
else
@@ -100,7 +109,8 @@ case "$1" in
checkproc /usr/bin/salt-minion
rc_status -v
elif [ -f $DEBIAN_VERSION ]; then
- if [ -f $LOCKFILE ]; then
+ findproc
+ if [ -n "$PROC_LIST" ]; then
RETVAL=0
echo "salt-minion is running."
else
@@ -113,7 +123,8 @@ case "$1" in
fi
;;
condrestart)
- [ -f $LOCKFILE ] && restart || :
+ findproc
+ [ -n "$PROC_LIST" ] && restart || :
;;
reload|force-reload)
echo "Can't reload configuration, you have to restart it"
16 debian/salt.salt-syndic.init
View
@@ -40,15 +40,23 @@ SERVICE=salt-syndic
PROCESS=salt-syndic
CONFIG_ARGS=" "
+PS_CMD="ps -e -o pid,args"
+PROC_LIST=""
+
RETVAL=0
+findproc() {
+ PROC_LIST=`$PS_CMD | grep $PROCESS | 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
- if [ -f $LOCKFILE ]; 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
@@ -70,7 +78,8 @@ stop() {
rc_status -v
elif [ -f $DEBIAN_VERSION ]; then
# Added this since Debian's start-stop-daemon doesn't support spawned processes
- if ps -ef | grep "/usr/bin/python /usr/bin/salt-syndic" | grep -v grep | awk '{print $2}' | xargs kill &> /dev/null; then
+ findproc
+ if echo $PROC_LIST | xargs kill >/dev/null 2>&1 ; then
echo -n "OK"
RETVAL=0
else
@@ -100,7 +109,8 @@ case "$1" in
checkproc /usr/bin/salt-syndic
rc_status -v
elif [ -f $DEBIAN_VERSION ]; then
- if [ -f $LOCKFILE ]; then
+ findproc
+ if [ -n "$PROC_LIST" ]; then
RETVAL=0
echo "salt-syndic is running."
else
17 doc/_templates/404.html
View
@@ -0,0 +1,17 @@
+{% extends "layout.html" %}
+{% set title = 'Page not found' %}
+
+{% block body %}
+<h1>404: Page not found</h1>
+
+<p>The page you are requesting cannot be found. Please try one of the following
+pages instead:</p>
+
+<ul>
+ <li><a href="{{ pathto("index") }}">Home page</a></li>
+ <li><a href="{{ pathto("topics/community") }}">Community</a></li>
+ <li><a href="{{ pathto("search") }}">Search</a></li>
+ <li><a href="{{ pathto("py-modindex") }}">Salt module index</a></li>
+ <li><a href="{{ pathto("home") }}">Salt Documentation</a></li>
+</ul>
+{% endblock %}
5 doc/conf.py
View
@@ -60,7 +60,10 @@
html_style = ['base-salt.css']
html_use_smartypants = False
-html_additional_pages = {'index': 'index.html'}
+html_additional_pages = {
+ 'index': 'index.html',
+ '404': '404.html',
+}
html_default_sidebars = [
'localtoc.html',
11 doc/example/templates/json-jinja.json
View
@@ -1,11 +0,0 @@
-{
- {% for item in 'vim','emacs','nano','butter' %}
- "{{ item }}": { "pkg": ["installed"] },
- {% endfor %}
- "salt": {
- "pkg": ["installed"],
- "service": ["running", "enabled", {"names": ["salt-master", "salt-minion"]}]},
- "cron": {
- "pkg": ["installed"],
- "service": ["running", "enabled", {"name": "crond"}]}
-}
11 doc/example/templates/json-mako.json
View
@@ -1,11 +0,0 @@
-{
- % for item in 'vim', 'emacs', 'nano', 'butter':
- "${item}": { "pkg": ["installed"] },
- % endfor
- "salt": {
- "pkg": ["installed"],
- "service": ["running", "enabled", {"names": ["salt-master", "salt-minion"]}]},
- "cron": {
- "pkg": ["installed"],
- "service": ["running", "enabled", {"name": "crond"}]}
-}
12 doc/example/templates/json.json
View
@@ -1,12 +0,0 @@
-{
- "vim": { "pkg": ["installed"] },
- "emacs": { "pkg": ["installed"] },
- "nano": { "pkg": ["installed"] },
- "butter": { "pkg": ["installed"] },
- "salt": {
- "pkg": ["installed"],
- "service": ["running", "enabled", {"names": ["salt-master", "salt-minion"]}]},
- "cron": {
- "pkg": ["installed"],
- "service": ["running", "enabled", {"name": "crond"}]}
-}
23 doc/example/templates/yaml-jinja.yml
View
@@ -1,23 +0,0 @@
-{% for item in 'vim','emacs','nano' %}
-{{ item }}:
- pkg:
- - installed
-{% endfor %}
-salt:
- pkg:
- - installed
- service:
- - running
- - require:
- - pkg: salt
- - names:
- - salt-master
- - salt-minion
-cronie:
- pkg:
- - installed
- service:
- - enabled
- - require:
- - pkg: cronie
- - name: crond
23 doc/example/templates/yaml-mako.yml
View
@@ -1,23 +0,0 @@
-% for item in 'vim', 'emacs', 'nano':
-${item}:
- pkg:
- - installed
-% endfor
-salt:
- pkg:
- - installed
- service:
- - running
- - require:
- - pkg: salt
- - names:
- - salt-master
- - salt-minion
-cronie:
- pkg:
- - installed
- service:
- - running
- - require:
- - pkg: cronie
- - name: crond
27 doc/example/templates/yaml.yml
View
@@ -1,27 +0,0 @@
-vim:
- pkg:
- - installed
-emacs:
- pkg:
- - installed
-nano:
- pkg:
- - latest
-salt:
- pkg:
- - installed
- service:
- - running
- - require:
- - pkg: vim
- - pkg: salt
- - service: cron
- - names:
- - salt-master
- - salt-minion
-cron:
- pkg:
- - installed
- service:
- - running
- - name: cronie
8 doc/home.rst
View
@@ -63,11 +63,11 @@ get much more out of Salt.
.. admonition:: Screencasts and presentations
+ * Thomas S. Hatch was `interviewed on episode 191 of FLOSS Weekly
+ <http://twit.tv/show/floss-weekly/191>`_.
* Presentation at the Salt Lake Linux User Group (SLLUG) in May 2011
- `video`_ | `slides`_ (PDF)
-
-.. _`video`: http://blip.tv/thomas-s-hatch/salt-0-8-7-presentation-5180182
-.. _`slides`: :download:`Salt.pdf`
+ `video <http://blip.tv/thomas-s-hatch/salt-0-8-7-presentation-5180182>`_
+ | :download:`slides <Salt.pdf>` (PDF)
Salt quick reference
====================
2  doc/man/salt-call.1
View
@@ -1,4 +1,4 @@
-.TH "SALT-CALL" "1" "November 06, 2011" "0.9.3" "Salt"
+.TH "SALT-CALL" "1" "November 27, 2011" "0.9.4" "Salt"
.SH NAME
salt-call \- salt-call Documentation
.
2  doc/man/salt-cp.1
View
@@ -1,4 +1,4 @@
-.TH "SALT-CP" "1" "November 06, 2011" "0.9.3" "Salt"
+.TH "SALT-CP" "1" "November 27, 2011" "0.9.4" "Salt"
.SH NAME
salt-cp \- salt-cp Documentation
.
2  doc/man/salt-key.1
View
@@ -1,4 +1,4 @@
-.TH "SALT-KEY" "1" "November 06, 2011" "0.9.3" "Salt"
+.TH "SALT-KEY" "1" "November 27, 2011" "0.9.4" "Salt"
.SH NAME
salt-key \- salt-key Documentation
.
2  doc/man/salt-master.1
View
@@ -1,4 +1,4 @@
-.TH "SALT-MASTER" "1" "November 06, 2011" "0.9.3" "Salt"
+.TH "SALT-MASTER" "1" "November 27, 2011" "0.9.4" "Salt"
.SH NAME
salt-master \- salt-master Documentation
.
2  doc/man/salt-minion.1
View
@@ -1,4 +1,4 @@
-.TH "SALT-MINION" "1" "November 06, 2011" "0.9.3" "Salt"
+.TH "SALT-MINION" "1" "November 27, 2011" "0.9.4" "Salt"
.SH NAME
salt-minion \- salt-minion Documentation
.
2  doc/man/salt-run.1
View
@@ -1,4 +1,4 @@
-.TH "SALT-RUN" "1" "November 06, 2011" "0.9.3" "Salt"
+.TH "SALT-RUN" "1" "November 27, 2011" "0.9.4" "Salt"
.SH NAME
salt-run \- salt-run Documentation
.
2  doc/man/salt-syndic.1
View
@@ -1,4 +1,4 @@
-.TH "SALT-SYNDIC" "1" "November 06, 2011" "0.9.3" "Salt"
+.TH "SALT-SYNDIC" "1" "November 27, 2011" "0.9.4" "Salt"
.SH NAME
salt-syndic \- salt-syndic Documentation
.
2  doc/man/salt.1
View
@@ -1,4 +1,4 @@
-.TH "SALT" "1" "November 06, 2011" "0.9.3" "Salt"
+.TH "SALT" "1" "November 27, 2011" "0.9.4" "Salt"
.SH NAME
salt \- salt
.
3,966 doc/man/salt.7
View
3,119 additions, 847 deletions not shown
36 doc/ref/file_server/index.rst
View
@@ -60,16 +60,16 @@ built in ``__opts__`` data can be passed:
import salt.minion
def get_file(path, dest, env='base'):
- '''
- Used to get a single file from the salt master
+ '''
+ Used to get a single file from the salt master
- CLI Example:
- salt '*' cp.get_file salt://vimrc /etc/vimrc
- '''
- # Create the FileClient object
- client = salt.minion.FileClient(__opts__)
- # Call get_file
- return client.get_file(path, dest, False, env)
+ CLI Example:
+ salt '*' cp.get_file salt://vimrc /etc/vimrc
+ '''
+ # Create the FileClient object
+ client = salt.minion.FileClient(__opts__)
+ # Call get_file
+ return client.get_file(path, dest, False, env)
Using the FileClient class outside of a minion module where the ``__opts__``
data is not available, it needs to be generated:
@@ -80,13 +80,13 @@ data is not available, it needs to be generated:
import salt.config
def get_file(path, dest, env='base'):
- '''
- Used to get a single file from the salt master
- '''
- # Get the configuration data
- opts = salt.config.minion_config('/etc/salt/minion')
- # Create the FileClient object
- client = salt.minion.FileClient(opts)
- # Call get_file
- return client.get_file(path, dest, False, env)
+ '''
+ Used to get a single file from the salt master
+ '''
+ # Get the configuration data
+ opts = salt.config.minion_config('/etc/salt/minion')
+ # Create the FileClient object
+ client = salt.minion.FileClient(opts)
+ # Call get_file
+ return client.get_file(path, dest, False, env)
5 doc/ref/modules/all/index.rst
View
@@ -12,12 +12,14 @@ Full list of builtin modules
apache
apt
+ archive
butterkvm
cluster
cmd
cp
cron
disk
+ ebuild
file
freebsdpkg
grains
@@ -44,6 +46,7 @@ Full list of builtin modules
state
status
test
+ tomcat
useradd
virt
- yum
+ yumpkg
6 doc/ref/modules/all/salt.modules.archive.rst
View
@@ -0,0 +1,6 @@
+====================
+salt.modules.archive
+====================
+
+.. automodule:: salt.modules.archive
+ :members:
6 doc/ref/modules/all/salt.modules.ebuild.rst
View
@@ -0,0 +1,6 @@
+===================
+salt.modules.ebuild
+===================
+
+.. automodule:: salt.modules.ebuild
+ :members:
6 doc/ref/modules/all/salt.modules.tomcat.rst
View
@@ -0,0 +1,6 @@
+===================
+salt.modules.tomcat
+===================
+
+.. automodule:: salt.modules.tomcat
+ :members:
6 doc/ref/modules/all/salt.modules.yum.rst
View
@@ -1,6 +0,0 @@
-================
-salt.modules.yum
-================
-
-.. automodule:: salt.modules.yum
- :members:
11 doc/ref/modules/all/salt.modules.yumpkg.rst
View
@@ -0,0 +1,11 @@
+===================
+salt.modules.yumpkg
+===================
+
+.. versionadded:: 0.9.4
+ This module replaces the "yum" module in previous releases. It is backward
+ compatibile and uses the native yum Python interface instead of the CLI
+ interface.
+
+.. automodule:: salt.modules.yumpkg
+ :members:
2  doc/ref/modules/index.rst
View
@@ -142,7 +142,7 @@ regardless of what the actual module is named.
The package manager modules are the best example of using the ``__virtual__``
function:
:blob:`salt/modules/pacman.py`
-:blob:`salt/modules/yum.py`
+:blob:`salt/modules/yumpkg.py`
:blob:`salt/modules/apt.py`
Documentation
55 doc/ref/states/failhard.rst
View
@@ -0,0 +1,55 @@
+======================
+Failhard Global Option
+======================
+
+Normally, when a state fails Salt continues to execute the remainder of the
+defined states and will only refuse to execute states that require the failed
+state.
+
+But the situation may exist, where you would want all state execution to stop
+if a single state execution fails. The capability to do this is called
+``failing hard``.
+
+State Level Failhard
+====================
+
+A single state can have a failhard set, this means that if this individual
+state fails that all state execution will immediately stop. This is a great
+thing to do if there is a state that sets up a critical config file and
+setting a require for each state that reads the config would be cumbersome.
+A good example of this would be setting up a package manager early on:
+
+.. code-block:: yaml
+
+ /etc/yum.repos.d/company.repo:
+ file:
+ - managed
+ - source: salt://company/yumrepo.conf
+ - user: root
+ - group: root
+ - mode: 644
+ - order: 1
+ - failhard: True
+
+In this situation, the yum repo is going to be configured before other states,
+and if it fails to lay down the config file, than no other states will be
+executed.
+
+Global Failhard
+===============
+
+It may be desired to have failhard be applied to every state that is executed,
+if this is the case, then failhard can be set in the master configuration
+file. Setting failhard in the master configuration file will result in failing
+hard when any minion gathering states from the master have a state fail.
+
+This is NOT the default behavior, normally Salt will only fail states that
+require a failed state.
+
+Using the global failhard is generally not recommended, since it can result
+in states not being executed or even checked. It can also be confusing to
+see states failhard if an admin is not actively aware that the failhard has
+been set.
+
+To use the global failhard set failhard: True in the master configuration
+file.
32 doc/ref/states/highstate.rst
View
@@ -5,6 +5,17 @@ Highstate data structure definitions
The Salt State Tree
===================
+.. glossary::
+
+ Top file
+ The main state file that instructs minions what environment and modules
+ to use during state execution.
+
+ Configurable via :conf_master:`state_top`.
+
+ State tree
+ A collection of ``sls`` files.
+
Include declaration
-------------------
@@ -43,7 +54,8 @@ ID declaration
Defines an individual highstate component. Always references a value of
a dictionary containing keys referencing :term:`state declarations
<state declaration>` and :term:`requisite declarations <requisite
- declaration>`. Can be overridden by :term:`name` and :term:`names`.
+ declaration>`. Can be overridden by a :term:`name declaration` or a
+ :term:`names declaration`.
Occurs on the top level or under the :term:`extend declaration`.
@@ -53,7 +65,7 @@ Extend declaration
.. glossary::
Extend declaration
- Used to extend a :term:`name` declaration from an included ``sls
+ Used to extend a :term:`name declaration` from an included ``sls
module``. The keys of the extend declaration always define existing
:term:`ID declarations <ID declaration>` which have been defined in
included ``sls modules``.
@@ -66,12 +78,14 @@ State declaration
.. glossary::
State declaration
- A list which contains one string defining the :term:`function` and any
- number of :term:`function arg` dictionaries.
+ A list which contains one string defining the :term:`function
+ declaration` and any number of :term:`function arg declaration`
+ dictionaries.
Can, optionally, contain a number of additional components like the
- name override components — :term:`name` and :term:`names <name>`. Can
- also contain :term:`requisite declarations <requisite declaration>`.
+ name override components — :term:`name <name declaration>` and
+ :term:`names <names declaration>`. Can also contain :term:`requisite
+ declarations <requisite declaration>`.
Occurs under an :term:`ID declaration`.
@@ -120,10 +134,10 @@ Function arg declaration
Function arg declaration
A single key dictionary referencing a Python type which is to be passed
- to the named :term:`function` as a parameter. The type must be the data
- type expected by the function.
+ to the named :term:`function declaration` as a parameter. The type must
+ be the data type expected by the function.
- Occurs under a :term:`function`.
+ Occurs under a :term:`function declaration`.
Name declaration
----------------
44 doc/ref/states/ordering.rst
View
@@ -0,0 +1,44 @@
+===============
+Ordering States
+===============
+
+When creating salt sls files, it is often important to ensure that they run in
+a specific order. While states will always execute in the same order, that
+order is not nessisarily defined the way you want it.
+
+A few tools exist in Salt to set up the corect state ordering, these tools
+consist of requisite declarations and order options.
+
+The Order Option
+================
+
+Before using the order option, remember that the majority of state ordering
+should be done with requisite statements, and that a requisite statement
+will override an order option.
+
+The order option is used by adding an order number to a state declaration
+with the option `order`:
+
+.. code-block:: yaml
+
+ vim:
+ pkg:
+ - installed
+ - order: 1
+
+By adding the order option to `1` this ensures that the vim package will be
+installed in tandem with any other state declaration set to the order `1`.
+
+Any state declared without an order option will be executed after all states
+with order options are executed.
+
+But this construct can only handle ordering states from the beggining.
+Sometimes you may want to send a state to the end of the line, to do this
+set the order to last:
+
+.. code-block:: yaml
+
+ vim:
+ pkg:
+ - installed
+ - order: last
107 doc/topics/installation.rst
View
@@ -6,6 +6,33 @@ The Salt system setup is amazingly simple, as this is one of the central design
goals of Salt. Setting up Salt only requires that the Salt :term:`master` be
running and the Salt :term:`minions <minion>` point to the master.
+.. admonition:: Salt dependencies
+
+ Salt should run on any Unix-like platform so long as the dependencies are
+ met.
+
+ * `Python 2.6`_
+ * `ZeroMQ`_ >= 2.1.9
+ * `pyzmq`_ >= 2.1.9 — ZeroMQ Python bindings
+ * `M2Crypto`_ — Python OpenSSL wrapper
+ * `PyCrypto`_ — The Python cryptography toolkit
+ * `YAML`_ — Python YAML bindings
+
+ Optional Dependencies:
+
+ * `Jinja2`_ — parsing Salt States (other renderers can be used via the
+ :conf_master:`renderer` setting).
+ * gcc — dynamic `Cython`_ module compiling
+
+.. _`Python 2.6`: http://python.org/download/
+.. _`ZeroMQ`: http://www.zeromq.org/
+.. _`pyzmq`: https://github.com/zeromq/pyzmq
+.. _`M2Crypto`: http://chandlerproject.org/Projects/MeTooCrypto
+.. _`YAML`: http://pyyaml.org/
+.. _`PyCrypto`: http://www.dlitz.net/software/pycrypto/
+.. _`Cython`: http://cython.org/
+.. _`Jinja2`: http://jinja.pocoo.org/
+
.. contents:: Instructions by operating system
:depth: 1
:local:
@@ -64,47 +91,49 @@ Salt can be easily installed from the Arch Linux AUR in one of two flavors:
Debian / Ubuntu
===============
-A deb package is `currently in testing`__. Until it is accepted the best way to
-install Salt on Debian and Ubuntu systems is as follows:
+Ubuntu
+------
-.. __: http://mentors.debian.net/package/salt
+A PPA is available until we can get packages into apt::
-1. Install the prerequisite packages::
+ aptitude -y install python-software-properties
+ add-apt-repository ppa:saltstack/salt
+ aptitude update
+ aptitude install salt
- aptitude install python-dev python-setuptools \
- python-yaml python-jinja2 \
- python-crypto python-m2crypto libzmq-dev
+.. admonition:: Installing ZeroMQ on Ubuntu Lucid (10.04 LTS)
- .. admonition:: Installing on Ubuntu Lucid (10.04 LTS)
+ The ZeroMQ package is available starting with Maverick but there are `PPA
+ packages available for Lucid`_ for both ZeroMQ and pyzmq. You will need to
+ also enable the following PPAs before running the commands above::
- The ZeroMQ package is available starting with Maverick but it is not
- yet available in Lucid backports. Fortunately, Chris Lea has made a
- `ZeroMQ PPA`_ available. Install it before installing Salt::
+ add-apt-repository ppa:chris-lea/libpgm
+ add-apt-repository ppa:chris-lea/zeromq
- aptitude install python-software-properties
- add-apt-repository ppa:chris-lea/zeromq
- add-apt-repository ppa:chris-lea/libpgm
- aptitude update
- aptitude install libzmq-dev
+.. _`PPA packages available for Lucid`: https://launchpad.net/~chris-lea/+archive/zeromq
- If you have an older version of ZeroMQ installed (perhaps from a
- previous installation of Salt) you may need to purge it: ``aptitude
- purge libzmq0``.
+Debian
+------
-2. Grab the latest Python ZeroMQ bindings::
+`A deb package is currently in testing`__. Until that is accepted you can
+install Salt via :command:`easy_install` or :command:`pip`::
- easy_install -U pyzmq
+ pip install salt
-3. Install Salt:
+.. __: http://mentors.debian.net/package/salt
- .. parsed-literal::
+.. admonition:: Installing ZeroMQ on Squeeze (Debian 6)
- easy_install -U --install-layout=deb |latest|
+ ZeroMQ packages are available in squeeze-backports.
- Please take note of the ``--install-layout=deb`` flag. This is important
- for a functioning installation of Salt.
+ 1. Add the following line to your :file:`/etc/apt/sources.list`::
-.. _`ZeroMQ PPA`: https://launchpad.net/~chris-lea/+archive/zeromq
+ deb http://backports.debian.org/debian-backports squeeze-backports main
+
+ 2. Run::
+
+ aptitude update
+ aptitude install libzmq1 python-zmq
Installing from source
======================
@@ -119,27 +148,3 @@ Installing from source
tar xvf salt-|version|.tar.gz
cd salt-|version|
python2 setup.py install
-
-Salt dependencies
------------------
-
-This is a basic Python setup, nothing fancy. Salt should run on any Unix-like
-platform so long as the dependencies are met:
-
-* `Python 2.6`_
-* `pyzmq`_ - ZeroMQ Python bindings
-* `M2Crypto`_ - Python OpenSSL wrapper
-* `YAML`_ - Python YAML bindings
-* `PyCrypto`_ - The Python cryptography toolkit
-
-.. _`Python 2.6`: http://python.org/download/
-.. _`pyzmq`: https://github.com/zeromq/pyzmq
-.. _`M2Crypto`: http://chandlerproject.org/Projects/MeTooCrypto
-.. _`YAML`: http://pyyaml.org/
-.. _`PyCrypto`: http://www.dlitz.net/software/pycrypto/
-
-Optional Dependencies:
-
-* gcc - dynamic `Cython`_ module compiling
-
-.. _`Cython`: http://cython.org/
146 doc/topics/releases/0.9.4.rst
View
@@ -0,0 +1,146 @@
+========================
+Salt 0.9.4 Release Notes
+========================
+
+Salt 0.9.4 has arrived. This is a critical update that repairs a number of
+key bugs found in 0.9.3. But this update is not without feature additions
+as well! 0.9.4 adds support for Gentoo portage to the pkg module and state
+system. Also there are 2 major new state additions, the failhard option and
+the ability to set up finite state ordering with the ``order`` option.
+
+This release also sees our largest increase in community contributions.
+These contributors have and continue to be the life blood of the Salt
+project, and the team continues to grow. I want to put out a big thanks to
+our new and existing contributors.
+
+Download!
+=========
+
+The Salt source can be downloaded from the salt github site:
+
+:download:`salt-0.9.4.tar.gz`
+
+Or from PiPy:
+
+http://pypi.python.org/packages/source/s/salt/salt-0.9.4.tar.gz
+
+For instructions on how to set up Salt please see the :doc:`installation
+instructions </topics/installation>`.
+
+New Features
+============
+
+Failhard State Option
+---------------------
+
+Normally, when a state fails Salt continues to execute the remainder of the
+defined states and will only refuse to execute states that require the failed
+state.
+
+But the situation may exist, where you would want all state execution to stop
+if a single state execution fails. The capability to do this is called
+``failing hard``.
+
+State Level Failhard
+````````````````````
+
+A single state can have a failhard set, this means that if this individual
+state fails that all state execution will immediately stop. This is a great
+thing to do if there is a state that sets up a critical config file and
+setting a require for each state that reads the config would be cumbersome.
+A good example of this would be setting up a package manager early on:
+
+.. code-block:: yaml
+
+ /etc/yum.repos.d/company.repo:
+ file:
+ - managed
+ - source: salt://company/yumrepo.conf
+ - user: root
+ - group: root
+ - mode: 644
+ - order: 1
+ - failhard: True
+
+In this situation, the yum repo is going to be configured before other states,
+and if it fails to lay down the config file, than no other states will be
+executed.
+
+Global Failhard
+```````````````
+
+It may be desired to have failhard be applied to every state that is executed,
+if this is the case, then failhard can be set in the master configuration
+file. Setting failhard in the master configuration file will result in failing
+hard when any minion gathering states from the master have a state fail.
+
+This is NOT the default behavior, normally Salt will only fail states that
+require a failed state.
+
+Using the global failhard is generally not recommended, since it can result
+in states not being executed or even checked. It can also be confusing to
+see states failhard if an admin is not actively aware that the failhard has
+been set.
+
+To use the global failhard set failhard: True in the master configuration
+
+Finite Ordering of State Execution
+----------------------------------
+
+When creating salt sls files, it is often important to ensure that they run in
+a specific order. While states will always execute in the same order, that
+order is not necessarily defined the way you want it.
+
+A few tools exist in Salt to set up the correct state ordering, these tools
+consist of requisite declarations and order options.
+
+The Order Option
+````````````````
+
+Before using the order option, remember that the majority of state ordering
+should be done with requisite statements, and that a requisite statement
+will override an order option.
+
+The order option is used by adding an order number to a state declaration
+with the option `order`:
+
+.. code-block:: yaml
+
+ vim:
+ pkg:
+ - installed
+ - order: 1
+
+By adding the order option to `1` this ensures that the vim package will be
+installed in tandem with any other state declaration set to the order `1`.
+
+Any state declared without an order option will be executed after all states
+with order options are executed.
+
+But this construct can only handle ordering states from the beginning.
+Sometimes you may want to send a state to the end of the line, to do this
+set the order to last:
+
+.. code-block:: yaml
+
+ vim:
+ pkg:
+ - installed
+ - order: last
+Substantial testing has gone into the state system and it is ready for real
+world usage. A great deal has been added to the documentation for states and
+the modules and functions available to states have been cleanly documented.
+
+A number of State System bugs have also been founds and repaired, the output
+from the state system has also been refined to be extremely clear and concise.
+
+Error reporting has also been introduced, issues found in sls files will now
+be clearly reported when executing Salt States.
+
+
+Gentoo Support
+--------------
+
+Additional experimental support has been added for Gentoo. This is found in
+the contribution from Doug Renn, aka nestegg.
+
2  doc/topics/tutorials/states_pt1.rst
View
@@ -55,7 +55,7 @@ minion matches is defined; for now simply specify all hosts (``*``).
The expressions can use any of the targeting mechanisms used by Salt —
minions can be matched by glob, pcre regular expression, or by :doc:`grains
- <ref/grains>`. For example::
+ </ref/grains>`. For example::
base:
'os:Fedora':
31 doc/topics/tutorials/states_pt2.rst
View
@@ -12,9 +12,9 @@ complicated, have requirements, and use even more Salt States.
Call multiple States
====================
-You can specify multiple :term:`state declarations` under an :term:`ID
-delcaration`. For example, a quick modification to our ``webserver.sls`` to
-also start Apache if it is not running:
+You can specify multiple :term:`state declarations <state declaration>` under
+an :term:`ID declaration`. For example, a quick modification to our
+``webserver.sls`` to also start Apache if it is not running:
.. code-block:: yaml
:linenos:
@@ -126,24 +126,33 @@ Verify that Apache is now serving your custom HTML.
.. admonition:: ``require`` vs. ``watch``
There are two :term:`requisite declarations <requisite declaration>`,
- “require” and “watch”. Not every state supports “watch”. In the :mod:`file
- state <salt.states.file>`, for example, Salt will watch a file for changes
- then take action if it does change.
+ “require” and “watch”. Not every state supports “watch”. The :mod:`service
+ state <salt.states.service>` does support “watch” and will restart a
+ service based on the watch condition.
For example, if you use Salt to install an Apache virtual host
- configuration file and want to restart Apache when that file is changed you
- could modify our Apache example from earlier as follows:
+ configuration file and want to restart Apache whenever that file is changed
+ you could modify our Apache example from earlier as follows:
.. code-block:: yaml
- :emphasize-lines: 6,7
+ :emphasize-lines: 1,2,3,4,11,12
+
+ /etc/httpd/extra/httpd-vhosts.conf:
+ file:
+ - managed
+ - source: salt://webserver/httpd-vhosts.conf
apache:
pkg:
- installed
service:
- running
- - watch:
- - file: /etc/httpd/extra/httpd-vhosts.conf
+ - watch:
+ - file: /etc/httpd/extra/httpd-vhosts.conf
+
+ If the pkg and service names differ on your OS or distro of choice you can
+ specify each one separately using a :term:`name declaration` which
+ explained in :doc:`Part 3 <states_pt3>`.
Next steps
==========
7 pkg/arch/PKGBUILD
View
@@ -1,18 +1,19 @@
# Maintainer: Thomas S Hatch <thatch45@gmail.com>
pkgname=salt
-pkgver=0.9.0
+pkgver=0.9.4
pkgrel=1
pkgdesc="A remote execution and communication system built on zeromq"
arch=(any)
-url="https://github.com/thatch45/salt"
+url="https://github.com/saltstack/salt"
license=("APACHE")
depends=('python2'
'python2-pyzmq'
'python-m2crypto'
'python2-yaml'
'pycrypto'
- 'python2-psutil')
+ 'python2-psutil'
+ 'python2-jinja')
backup=('etc/salt/master'
'etc/salt/minion')
makedepends=()
5 pkg/arch/PKGBUILD-git
View
@@ -12,7 +12,8 @@ depends=('python2'
'python-m2crypto'
'python2-yaml'
'pycrypto'
- 'python2-psutil')
+ 'python2-psutil'
+ 'python2-jinja')
makedepends=('git')
provides=()
backup=('etc/salt/master'
@@ -25,7 +26,7 @@ md5sums=('1594591acb0a266854186a694da21103'
'21ab2eac231e9f61bf002ba5f16f8a3d'
'09683ef4966e401761f7d2db6ad4b692')
-_gitroot="git://github.com/thatch45/salt.git"
+_gitroot="git://github.com/saltstack/salt.git"
_gitname="salt"
build() {
2  salt/__init__.py
View
@@ -2,7 +2,7 @@
Make me some salt!
'''
-__version_info__ = (0, 9, 4, 'pre')
+__version_info__ = (0, 9, 4)
__version__ = '.'.join(map(str, __version_info__))
# Import python libs
5 salt/cli/__init__.py
View
@@ -39,7 +39,8 @@ def __parse(self):
'''
Parse the command line
'''
- parser = optparse.OptionParser(version="%%prog %s" % VERSION)
+ usage = "%prog [options] '<target>' <function> [arguments]"
+ parser = optparse.OptionParser(version="%%prog %s" % VERSION, usage=usage)
parser.add_option('-t',
'--timeout',
@@ -152,7 +153,7 @@ def __parse(self):
if len(args) < 1:
err = ('Please pass in a command to query the old salt '
'calls for.')
- sys.stderr.write(err, + '\n')
+ sys.stderr.write(err + '\n')
sys.exit('2')
opts['cmd'] = args[0]
else:
2  salt/config.py
View
@@ -61,6 +61,7 @@ def minion_config(path):
'cachedir': '/var/cache/salt',
'conf_file': path,
'renderer': 'yaml_jinja',
+ 'failhard': False,
'disable_modules': [],
'disable_returners': [],
'module_dirs': [],
@@ -122,6 +123,7 @@ def master_config(path):
'open_mode': False,
'auto_accept': False,
'renderer': 'yaml_jinja',
+ 'failhard': False,
'state_top': 'top.sls',
'order_masters': False,
'log_file': '/var/log/salt/master',
28 salt/grains/core.py
View
@@ -16,6 +16,7 @@
import os
import socket
import subprocess
+import sys
def _kernel():
@@ -180,7 +181,7 @@ def os_data():
grains['os'] = 'Arch'
elif os.path.isfile('/etc/debian_version'):
grains['os'] = 'Debian'
- elif os.path.isfile('/etc/gentoo-version'):
+ elif os.path.isfile('/etc/gentoo-release'):
grains['os'] = 'Gentoo'
elif os.path.isfile('/etc/fedora-version'):
grains['os'] = 'Fedora'
@@ -271,3 +272,28 @@ def path():
# Provides:
# path
return {'path': os.environ['PATH'].strip()}
+
+def pythonversion():
+ '''
+ Return the Python version
+ '''
+ # Provides:
+ # pythonversion
+ return {'pythonversion': list(sys.version_info)}
+
+def pythonpath():
+ '''
+ Return the Python path
+ '''
+ # Provides:
+ # pythonpath
+ return {'pythonpath': sys.path}
+
+def saltpath():
+ '''
+ Return the path of the salt module
+ '''
+ # Provides:
+ # saltpath
+ path = os.path.abspath(os.path.join(__file__, os.path.pardir))
+ return {'saltpath': os.path.dirname(path)}
6 salt/loader.py
View
@@ -105,12 +105,12 @@ def grains(opts):
return grains
-# FIXME: mutable types as default parameter values, NO!
-# http://goo.gl/ToU2z
-def call(fun, args=[], dirs=[]):
+def call(fun, **kwargs):
'''
Directly call a function inside a loader directory
'''
+ args = kwargs.get('args', [])
+ dirs = kwargs.get('dirs', [])
module_dirs = [
os.path.join(salt_base_path, 'modules'),
] + dirs
23 salt/master.py
View
@@ -35,7 +35,7 @@ def prep_jid(cachedir, load):
job id directory.
'''
jid_root = os.path.join(cachedir, 'jobs')
- jid = "{:%Y%m%d%H%M%S%f}".format(datetime.datetime.now())
+ jid = "{0:%Y%m%d%H%M%S%f}".format(datetime.datetime.now())
jid_dir = os.path.join(jid_root, jid)
if not os.path.isdir(jid_dir):
@@ -72,12 +72,13 @@ def __prep_key(self):
'''
log.info('Preparing the root key for local communication')
keyfile = os.path.join(self.opts['cachedir'], '.root_key')
- key = salt.crypt.Crypticle.generate_key_string()
if os.path.isfile(keyfile):
return open(keyfile, 'r').read()
- open(keyfile, 'w+').write(key)
- os.chmod(keyfile, 256)
- return key
+ else:
+ key = salt.crypt.Crypticle.generate_key_string()
+ open(keyfile, 'w+').write(key)
+ os.chmod(keyfile, 256)
+ return key
class Master(SMaster):
@@ -95,7 +96,7 @@ def _clear_old_jobs(self):
Clean out the old jobs
'''
while True:
- cur = "{:%Y%m%d%H}".format(datetime.datetime.now())
+ cur = "{0:%Y%m%d%H}".format(datetime.datetime.now())
if self.opts['keep_jobs'] == 0:
return
@@ -497,17 +498,13 @@ def minion_publish(self, clear_load):
if not good:
return {}
# Set up the publication payload
- jid_dir = os.path.join(
- self.opts['cachedir'],
- 'jobs',
- clear_load['jid'])
- pickle.dump(clear_load, open(os.path.join(jid_dir, '.load.p'), 'w+'))
+ jid = prep_jid(self.opts['cachedir'], clear_load)
payload = {'enc': 'aes'}
load = {
'fun': clear_load['fun'],
'arg': clear_load['arg'],
'tgt': clear_load['tgt'],
- 'jid': clear_load['jid'],
+ 'jid': jid,
'ret': clear_load['ret'],
}
expr_form = 'glob'
@@ -529,7 +526,7 @@ def minion_publish(self, clear_load):
pub_sock.send(salt.payload.package(payload))
# Run the client get_returns method
return self.local.get_returns(
- clear_load['jid'],
+ jid,
self.local.check_minions(
clear_load['tgt'],
expr_form
53 salt/modules/apt.py
View
@@ -2,9 +2,6 @@
Support for APT (Advanced Packaging Tool)
'''
-# FIXME: we want module internal calls rather than using subprocess direclty
-import subprocess
-
def __virtual__():
'''
@@ -23,11 +20,9 @@ def available_version(name):
salt '*' pkg.available_version <package name>
'''
version = ''
- cmd = 'apt-cache show ' + name + ' | grep Version'
+ cmd = 'apt-cache show {0} | grep Version'.format(name)
- out = subprocess.Popen(cmd,
- shell=True,
- stdout=subprocess.PIPE).communicate()[0]
+ out = __salt__['cmd.run_stdout'](cmd)
version_list = out.split()
if len(version_list) >= 2:
@@ -64,10 +59,9 @@ def refresh_db():
salt '*' pkg.refresh_db
'''
- cmd = 'aptitude update'
- out = subprocess.Popen(cmd,
- shell=True,
- stdout=subprocess.PIPE).communicate()[0].split('\n')
+ cmd = 'apt-get update'
+
+ out = __salt__['cmd.run_stdout'](cmd)
servers = {}
for line in out:
@@ -96,13 +90,13 @@ def install(pkg, refresh=False):
salt '*' pkg.install <package name>
'''
- if(refresh):
+ if refresh:
refresh_db()
ret_pkgs = {}
old_pkgs = list_pkgs()
- cmd = 'aptitude -y install ' + pkg
- subprocess.call(cmd, shell=True)
+ cmd = 'apt-get -y install {0}'.format(pkg)
+ __salt__['cmd.retcode'](cmd)
new_pkgs = list_pkgs()
for pkg in new_pkgs:
@@ -132,10 +126,9 @@ def remove(pkg):
ret_pkgs = []
old_pkgs = list_pkgs()
- cmd = 'aptitude -y remove ' + pkg
- subprocess.call(cmd, shell=True)
- new = list_pkgs()
-
+ cmd = 'apt-get -y remove {0}'.format(pkg)
+ __salt__['cmd.retcode'](cmd)
+ new_pkgs = list_pkgs()
for pkg in old_pkgs:
if pkg not in new_pkgs:
ret_pkgs.append(pkg)
@@ -158,10 +151,11 @@ def purge(pkg):
old_pkgs = list_pkgs()
# Remove inital package
- purge_cmd = 'aptitude -y purge ' + pkg
- subprocess.call(purge_cmd, shell=True)
- new = list_pkgs()
-
+ purge_cmd = 'apt-get -y purge {0}'.format(pkg)
+ __salt__['cmd.retcode'](purge_cmd)
+
+ new_pkgs = list_pkgs()
+
for pkg in old_pkgs:
if pkg not in new_pkgs:
ret_pkgs.append(pkg)
@@ -169,7 +163,6 @@ def purge(pkg):
return ret_pkgs
-# FIXME: Unused argument 'refresh'? Undefined variable 'update_repos'?
def upgrade(refresh=True):
'''
Upgrades all packages via aptitude full-upgrade
@@ -189,13 +182,13 @@ def upgrade(refresh=True):
salt '*' pkg.upgrade
'''
- if(update_repos):
+ if refresh:
refresh_db()
ret_pkgs = {}
old_pkgs = list_pkgs()
- cmd = 'aptitude -y full-upgrade'
- subprocess.call(cmd, shell=True)
+ cmd = 'apt-get -y dist-upgrade'
+ __salt__['cmd.retcode'](cmd)
new_pkgs = list_pkgs()
for pkg in new_pkgs:
@@ -223,13 +216,11 @@ def list_pkgs(regex_string=""):
salt '*' pkg.list_pkgs
'''
ret = {}
- cmd = 'dpkg --list ' + regex_string
+ cmd = 'dpkg --list {0}'.format(regex_string)
- out = subprocess.Popen(cmd,
- shell=True,
- stdout=subprocess.PIPE).communicate()[0].split('\n')
+ out = __salt__['cmd.run_stdout'](cmd)
- for line in out:
+ for line in out.split('\n'):
cols = line.split()
if len(cols) and cols[0].count('ii'):
ret[cols[1]] = cols[2]
219 salt/modules/ebuild.py
View
@@ -0,0 +1,219 @@
+'''
+Support for Portage
+'''
+
+try:
+ import portage
+except ImportError:
+ None
+
+def __virtual__():
+ '''
+ Confirm this module is on a Gentoo based system
+ '''
+ return 'pkg' if __grains__['os'] == 'Gentoo' else False
+
+def _vartree():
+ return portage.db[portage.root]['vartree']
+
+def _porttree():
+ return portage.db[portage.root]['porttree']
+
+def _cpv_to_name(cpv):
+ if cpv == '':
+ return ''
+ return str(portage.cpv_getkey(cpv))
+
+def _cpv_to_version(cpv):
+ if cpv == '':
+ return ''
+ return str(cpv[len(_cpv_to_name(cpv)+'-'):])
+
+def available_version(name):
+ '''
+ The available version of the package in the repository
+
+ CLI Example::
+
+ salt '*' pkg.available_version <package name>
+ '''
+ return _cpv_to_version(_porttree().dep_bestmatch(name))
+
+def version(name):
+ '''
+ Returns a version if the package is installed, else returns an empty string
+
+ CLI Example::
+
+ salt '*' pkg.version <package name>
+ '''
+ return _cpv_to_version(_vartree().dep_bestmatch(name))
+
+def list_pkgs():
+ '''
+ List the packages currently installed in a dict::
+
+ {'<package_name>': '<version>'}
+
+ CLI Example::
+
+ salt '*' pkg.list_pkgs
+ '''
+ ret = {}
+ pkgs = _vartree().dbapi.cpv_all()
+ for cpv in pkgs:
+ ret[_cpv_to_name(cpv)] = _cpv_to_version(cpv)
+ return ret
+
+def refresh_db():
+ '''
+ Updates the portage tree (emerge --sync)
+
+ CLI Example::
+
+ salt '*' pkg.refresh_db
+ '''
+ if __salt__['cmd.retcode']('emerge --sync --quiet'):
+ return False
+ else:
+ return True
+
+def install(pkg, refresh=False):
+ '''
+ Install the passed package
+
+ Return a dict containing the new package names and versions::
+
+ {'<package>': {'old': '<old-version>',
+ 'new': '<new-version>']}
+
+ CLI Example::
+
+ salt '*' pkg.install <package name>
+ '''
+ if(refresh):
+ refresh_db()
+
+ ret_pkgs = {}
+ old_pkgs = list_pkgs()
+ cmd = 'emerge --quiet {0}'.format(pkg)
+ __salt__['cmd.retcode'](cmd)
+ new_pkgs = list_pkgs()
+
+ for pkg in new_pkgs:
+ if old_pkgs.has_key(pkg):
+ if old_pkgs[pkg] == new_pkgs[pkg]:
+ continue
+ else:
+ ret_pkgs[pkg] = {'old': old_pkgs[pkg],
+ 'new': new_pkgs[pkg]}
+ else:
+ ret_pkgs[pkg] = {'old': '',
+ 'new': new_pkgs[pkg]}
+
+ return ret_pkgs
+
+def update(pkg, refresh=False):
+ '''
+ Updates the passed package (emerge --update package)
+
+ Return a dict containing the new package names and versions::
+
+ {'<package>': {'old': '<old-version>',
+ 'new': '<new-version>']}
+
+ CLI Example::
+
+ salt '*' pkg.update <package name>
+ '''
+ if(refresh):
+ refresh_db()
+
+ ret_pkgs = {}
+ old_pkgs = list_pkgs()
+ cmd = 'emerge --update --quiet {0}'.format(pkg)
+ __salt__['cmd.retcode'](cmd)
+ new_pkgs = list_pkgs()
+
+ for pkg in new_pkgs:
+ if old_pkgs.has_key(pkg):
+ if old_pkgs[pkg] == new_pkgs[pkg]:
+ continue
+ else:
+ ret_pkgs[pkg] = {'old': old_pkgs[pkg],
+ 'new': new_pkgs[pkg]}
+ else:
+ ret_pkgs[pkg] = {'old': '',
+ 'new': new_pkgs[pkg]}
+
+ return ret_pkgs
+
+def upgrade(refresh=False):
+ '''
+ Run a full system upgrade (emerge --update world)
+
+ Return a dict containing the new package names and versions::
+
+ {'<package>': {'old': '<old-version>',
+ 'new': '<new-version>']}
+
+ CLI Example::
+
+ salt '*' pkg.upgrade
+ '''
+ if(refresh):
+ refresh_db()
+
+ ret_pkgs = {}
+ old_pkgs = list_pkgs()
+ __salt__['cmd.retcode']('emerge --update --quiet world')
+ new_pkgs = list_pkgs()
+
+ for pkg in new_pkgs:
+ if old_pkgs.has_key(pkg):
+ if old_pkgs[pkg] == new_pkgs[pkg]:
+ continue
+ else:
+ ret_pkgs[pkg] = {'old': old_pkgs[pkg],
+ 'new': new_pkgs[pkg]}
+ else:
+ ret_pkgs[pkg] = {'old': '',
+ 'new': new_pkgs[pkg]}
+
+ return ret_pkgs
+
+def remove(pkg):
+ '''
+ Remove a single package via emerge --unmerge
+
+ Return a list containing the names of the removed packages:
+
+ CLI Example::
+
+ salt '*' pkg.remove <package name>
+ '''
+ ret_pkgs = []
+ old_pkgs = list_pkgs()
+
+ cmd = 'emerge --unmerge --quiet --quiet-unmerge-warn {0}'.format(pkg)
+ __salt__['cmd.retcode'](cmd)
+ new_pkgs = list_pkgs()
+
+ for pkg in old_pkgs:
+ if not new_pkgs.has_key(pkg):
+ ret_pkgs.append(pkg)
+
+ return ret_pkgs
+
+def purge(pkg):
+ '''
+ Portage does not have a purge, this function calls remove
+
+ Return a list containing the removed packages:
+
+ CLI Example::
+
+ salt '*' pkg.purge <package name>
+
+ '''
+ return remove(pkg)
1  salt/modules/network.py
View
@@ -138,3 +138,4 @@ def isportopen(host, port):
out = sock.connect_ex((_sanitize_host(host), int(port)))
return out
+
14 salt/modules/publish.py
View
@@ -17,16 +17,16 @@ def _get_socket():
return socket
-def publish(tgt, fun, arg, expr_form='glob', returner=''):
+def publish(tgt, fun, arg=None, expr_form='glob', returner=''):
'''
Publish a command from the minion out to other minions, publications need
to be enabled on the Salt master and the minion needs to have permission
to publish the command. The Salt master will also prevent a recursive
publication loop, this means that a minion cannot command another minion
- to command another minion as that would create an infinate command loop.
+ to command another minion as that would create an infinite command loop.
- The arguments sent to the minion publish function are seperated with
- commas. This means that a minion who is executing a command with multiple
+ The arguments sent to the minion publish function are separated with
+ commas. This means that for a minion executing a command with multiple
args it will look like this::
salt system.example.com publish.publish '*' user.add 'foo,1020,1020'
@@ -38,13 +38,17 @@ def publish(tgt, fun, arg, expr_form='glob', returner=''):
if fun == 'publish.publish':
# Need to log something here
return {}
+ if not arg:
+ arg = []
+ else:
+ arg = arg.split(',')
auth = salt.crypt.SAuth(__opts__)
tok = auth.gen_token('salt')
payload = {'enc': 'aes'}
load = {
'cmd': 'minion_publish',
'fun': fun,
- 'arg': arg.split(','),
+ 'arg': arg,
'tgt': tgt,
'ret': returner,
'tok': tok,
2  salt/modules/pw_group.py
View
@@ -23,7 +23,7 @@ def add(name, gid=None):
cmd = 'pw groupadd '
if gid:
cmd += '-g {0} '.format(gid)
- cmd += name
+ cmd = '{0} -n {1}'.format(cmd, name)
ret = __salt__['cmd.run_all'](cmd)
return not ret['retcode']
4 salt/modules/pw_user.py
View
@@ -27,13 +27,15 @@ def add(name,
salt '*' user.add name <uid> <gid> <groups> <home> <shell>
'''
+ if type(groups) == type(str()):
+ groups = groups.split(',')
cmd = 'pw useradd -s {0} '.format(shell)
if uid:
cmd += '-u {0} '.format(uid)
if gid:
cmd += '-g {0} '.format(gid)
if groups:
- cmd += '-G {0} '.format(groups)
+ cmd += '-G {0} '.format(','.join(groups))
if home:
cmd += '-m -b {0} '.format(os.dirname(home))
cmd += '-n {0}'.format(name)
1  salt/modules/service.py
View
@@ -11,6 +11,7 @@
'Fedora': '/etc/init.d',
'RedHat': '/etc/init.d',
'Ubuntu': '/etc/init.d',
+ 'Gentoo': '/etc/init.d',
}
5 salt/modules/shadow.py
View
@@ -8,7 +8,7 @@
def info(name):
'''
- Return the information for the specified user
+ Return information for the specified user
CLI Example::
@@ -40,7 +40,7 @@ def info(name):
def set_password(name, password):
'''
- Set the password for a named user, the password must be a properly defined
+ Set the password for a named user. The password must be a properly defined
hash, the password hash can be generated with this command:
``openssl passwd -1 <plaintext password>``
@@ -62,7 +62,6 @@ def set_password(name, password):
line = ':'.join(comps)
lines.append('{0}\n'.format(line))
open(s_file, 'w+').writelines(lines)
- print name
uinfo = info(name)
if uinfo['pwd'] == password:
return True
808 salt/modules/solr.py
View
@@ -1,28 +1,82 @@
-"""
-Manage Apache Solr
+'''
+Apache Solr Salt Module
+=======================
-This module uses http requests to talk to the Apache Solr request handlers to
-gather information and report errors. Because of this the minion doesn't
-nescessarily need to reside on the actual slave. However if you want to use
-the signal function the minion must reside on the physical Solr host.
+Author: Jed Glazner
+Version: 0.2
+Modified: 9/20/2011
+
+This module uses http requests to talk to the apache solr request handlers
+to gather information and report errors. Because of this the minion doesn't
+nescessarily need to reside on the actual slave. However if you want to
+use the signal function the minion must reside on the physical solr host.
This module supports multi-core and standard setups. Certain methods are
-master/slave specific. Make sure you set the ``solr.type``. If you have
+master/slave specific. Make sure you set the solr.type. If you have
questions or want a feature request please ask.
-"""
-
+Coming Features in 0.3
+----------------------
+
+1. Add command for checking for replication failures on slaves
+2. Improve match_index_versions since it's pointless on busy solr masters
+3. Add additional local fs checks for backups to make sure they succeeded
+
+Override these in the minion config
+-----------------------------------
+
+solr.cores
+ A list of core names eg ['core1','core2'].
+ An empty list indicates non-multicore setup.
+solr.baseurl
+ The root level url to access solr via http
+solr.request_timeout
+ The number of seconds before timing out an http/https/ftp request. If
+ nothing is specified then the python global timeout setting is used.
+solr.type
+ Possible values are 'master' or 'slave'
+solr.backup_path
+ The path to store your backups. If you are using cores and you can specify
+ to append the core name to the path in the backup method.
+solr.num_backups
+ For versions of solr >= 3.5. Indicates the number of backups to keep. This
+ option is ignored if your version is less.
+solr.init_script
+ The full path to your init script with start/stop options
+solr.dih.options
+ A list of options to pass to the dih.
+
+Required Options for DIH
+------------------------
+
+clean : False
+ Clear the index before importing
+commit : True
+ Commit the documents to the index upon completion
+optimize : True
+ Optimize the index after commit is complete
+verbose : True
+ Get verbose output
+'''
+
+import urllib2
import json
-import urllib
-
+import socket
+import os
-# Override these in the minion config. solr.cores as an empty list indicates
-# this is not a multi-core setup.
+#sane defaults
__opts__ = {'solr.cores': [],
'solr.baseurl': 'http://localhost:8983/solr',
- 'solr.type': 'master',
- 'solr.init_script': '/etc/rc.d/solr'}
+ 'solr.type':'master',
+ 'solr.request_timeout': None,
+ 'solr.init_script': '/etc/rc.d/solr',
+ 'solr.dih.import_options': {'clean':False, 'optimize':True,
+ 'commit':True, 'verbose':False},
+ 'solr.backup_path': None,
+ 'solr.num_backups':1
+ }
+########################## PRIVATE METHODS ##############################
def __virtual__():
'''
@@ -31,14 +85,18 @@ def __virtual__():
Return: str/bool Indicates weather solr is present or not
- TODO: currently __salt__ is not available to call in this method because
+ TODO:// currently __salt__ is not available to call in this method because
all the salt modules have not been loaded yet. Use a grains module?
'''
- # FIXME: this module should only be available if it is installed
return 'solr'
+ names = ['solr', 'apache-solr']
+ for name in names:
+ if __salt__['pkg.version'](name):
+ return 'solr'
+ return False
-def __check_for_cores__():
+def _check_for_cores():
'''
PRIVATE METHOD
Checks to see if using_cores has been set or not. if it's been set
@@ -51,7 +109,6 @@ def __check_for_cores__():
else:
return False
-
def _get_return_dict(success=True, data={}, errors=[], warnings=[]):
'''
PRIVATE METHOD
@@ -62,20 +119,19 @@ def _get_return_dict(success=True, data={}, errors=[], warnings=[]):
Param: list errors Default = []
Param: list warnings Default= []
'''
- ret = {'success': success,
- 'data':data,
- 'errors':errors,
+ ret = {'success':success,
+ 'data':data,
+ 'errors':errors,
'warnings':warnings}
return ret
-
def _update_return_dict(ret, success, data, errors, warnings=[]):
'''
PRIVATE METHOD
Updates the return dictionary and returns it.
- Param: dict ret: The origional returning dictionary to update
+ Param: dict ret: The original returning dictionary to update
Param: bool success: Indicates if the call was successful.
Param: dict data: The data to update.
Param: list errors: Errors list to append to the return
@@ -85,31 +141,33 @@ def _update_return_dict(ret, success, data, errors, warnings=[]):
ret['data'].update(data)
ret['errors'] = ret['errors'] + errors
ret['warnings'] = ret['warnings'] + warnings
- return ret
+ return ret
-def _format_url(handler, core_name=None, extra=[]):
+def _format_url(handler,core_name=None,extra=[]):
'''
PRIVATE METHOD
Formats the url based on parameters, and if cores are used or not
Param: str request_handler: The request handler to hit
- Param: str core_name (None): The name of the solr core if using cores.
+ Param: str core_name (None): The name of the solr core if using cores.
Leave this blank if you are not using cores or
- if you want to check all cores.
+ if you want to check all cores.
Param: list extra ([]): A list of additional name value pairs ['name=value]
Return: str formatted url
'''
baseurl = __opts__['solr.baseurl']
if core_name is None:
- return "{0}/{1}?wt=json".format(baseurl, handler)
+ if extra is None:
+ return "{0}/{1}?wt=json".format(baseurl, handler)
+ else:
+ return "{0}/{1}?wt=json&{2}".format(baseurl, handler,"&".join(extra))
else:
if extra is None:
return "{0}/{1}/{2}?wt=json".format(baseurl, core_name, handler)
else:
- return "{0}/{1}/{2}?wt=json&{3}".format(baseurl, core_name,
- handler, "&".join(extra))
-
+ return "{0}/{1}/{2}?wt=json&{3}".format(baseurl, core_name,
+ handler,"&".join(extra))
def _http_request(url):
'''
@@ -122,50 +180,151 @@ def _http_request(url):
TODO://Add a timeout param.
'''
try:
- data = json.load(urllib.urlopen(url))
- return _get_return_dict(True, data, [])
+ request_timeout = __opts__['solr.request_timeout']
+ if request_timeout is None:
+ data = json.load(urllib2.urlopen(url))
+ else:
+ data = json.load(urllib2.urlopen(url,timeout=request_timeout))
+ return _get_return_dict(True, data,[])
except Exception as e:
- return _get_return_dict(False, {}, ["{0} : {1}".format(url, e)])
-
+ return _get_return_dict(False, {}, ["{0} : {1}".format(url,e)])
def _replication_request(replication_command, core_name=None, params=[]):
'''
PRIVATE METHOD
- Performs the requested replication command and returns a dictionary with
- success, errors and data as keys. The data object will contain the json
+ Performs the requested replication command and returns a dictionary with
+ success, errors and data as keys. The data object will contain the json
response.
Param: str replication_command: The replication command to execute
- Param: str core_name (None): The name of the solr core if using cores.
+ Param: str core_name (None): The name of the solr core if using cores.
Leave this blank if you are not using cores or
if you want to check all cores.
- Param: list params ([]): Any additional parameters you want send.
+ Param: list params ([]): Any additional parameters you want send.
Should be a list of strings in name=value format.
Return: dict {'success':bool, 'data':dict, 'errors':list, 'warnings':list}
'''
extra = ["command={0}".format(replication_command)] + params
- url = _format_url('replication', core_name=core_name, extra=extra)
+ url = _format_url('replication',core_name=core_name,extra=extra)
return _http_request(url)
-
def _get_admin_info(command, core_name=None):
'''
PRIVATE METHOD
- Calls the _http_request method and passes the admin command to execute
- and stores the data. This data is fairly static but should be refreshed
- periodically to make sure everying this ok. The data object will contain
- the json response.
+ Calls the _http_request method and passes the admin command to execute
+ and stores the data. This data is fairly static but should be refreshed
+ periodically to make sure everything this OK. The data object will contain
+ the json response.
Param: str command: The admin command to run
- Param: str core_name (None): The name of the solr core if using cores.
+ Param: str core_name (None): The name of the solr core if using cores.
Leave this blank if you are not using cores or
if you want to check all cores.
Return: dict {'success':bool, 'data':dict, 'errors':list, 'warnings':list}
'''
url = _format_url("admin/{0}".format(command), core_name=core_name)
- resp = _http_request(url)