Merge branch 'master' of github.com:thatch45/salt

Conflicts:
	salt/minion.py
This commit is contained in:
Thomas S Hatch 2011-03-14 22:32:47 -06:00
commit 395af9faef
8 changed files with 117 additions and 10 deletions

View file

@ -9,7 +9,9 @@ url="https://github.com/thatch45/salt"
license=("APACHE")
depends=('python2'
'pyzmq'
'python-m2crypto')
'python-m2crypto'
'python-yaml'
'pycrypto')
makedepends=()
optdepends=()
options=()

View file

@ -35,9 +35,16 @@ class SaltCMD(object):
'--pcre',
default=False,
dest='pcre',
action='store_true'
action='store_true',
help='Instead of using shell globs to evaluate the target'\
+ ' servers, use pcre regular expressions')
parser.add_option('-L',
'--list',
default=False,
dest='list_',
action='store_true',
help='Instead of using shell globs to evaluate the target'\
+ ' servers, take a comma delimited list of servers.')
parser.add_option('-Q',
'--query',
dest='query',
@ -53,6 +60,7 @@ class SaltCMD(object):
opts['timeout'] = options.timeout
opts['pcre'] = options.pcre
opts['list'] = options.list_
if options.query:
opts['query'] = options.query
if len(args) < 1:
@ -62,7 +70,10 @@ class SaltCMD(object):
sys.exit('2')
opts['cmd'] = args[0]
else:
opts['tgt'] = args[0]
if opts['list']:
opts['tgt'] = args[0].split(',')
else:
opts['tgt'] = args[0]
opts['fun'] = args[1]
opts['arg'] = args[2:]
@ -73,7 +84,7 @@ class SaltCMD(object):
Execute the salt command line
'''
local = salt.client.LocalClient()
if self.opts['query']:
if self.opts.has_key('query'):
print local.find_cmd(self.opts['cmd'])
else:
args = [self.opts['tgt'],
@ -83,5 +94,29 @@ class SaltCMD(object):
]
if self.opts['pcre']:
args.append('pcre')
print local.cmd(*args)
elif self.opts['list']:
args.append('list')
ret = local.cmd(*args)
# Handle special case commands
if self.opts['fun'] == 'sys.doc':
self._print_docs(ret)
else:
print ret
def _print_docs(self, ret):
'''
Print out the docstrings for all of the functions on the minions
'''
docs = {}
for host in ret:
for fun in ret[host]:
if not docs.has_key(fun):
if ret[host][fun]:
docs[fun] = ret[host][fun]
for fun in docs:
print fun + ':'
print docs[fun]
print ''

View file

@ -77,6 +77,17 @@ class LocalClient(object):
os.chdir(cwd)
return ret
def _check_list_minions(self, expr):
'''
Return the minions found by looking via a list
'''
ret = []
for fn_ in os.listdir(os.path.join(self.opts['pki_dir'], 'minions')):
if expr.count(fn_):
if not ret.count(fn_):
ret.append(fn_)
return ret
def _check_pcre_minions(self, expr):
'''
Return the minions found by looking via regular expresions
@ -153,7 +164,9 @@ class LocalClient(object):
returns to make sure everyone has checked back in.
'''
return {'glob': self._check_glob_minions,
'pcre': self._check_pcre_minions}[expr_form](expr)
'pcre': self._check_pcre_minions,
'list': self._check_list_minions,
}[expr_form](expr)
def pub(self, tgt, fun, arg=(), expr_form='glob'):
'''
@ -193,8 +206,8 @@ class LocalClient(object):
tgt=tgt,
fun=fun,
arg=arg,
key=self.key)
package['tgt_type': expr_form]
key=self.key,
tgt_type=expr_form)
# Prep zmq
context = zmq.Context()
socket = context.socket(zmq.REQ)

View file

@ -59,15 +59,30 @@ class Minion(object):
for mod in mods:
if self.opts['disable_modules'].count(mod):
continue
module = importlib.import_module('salt.modules.' + mod)
try:
module = importlib.import_module('salt.modules.' + mod)
except:
continue
for attr in dir(module):
if attr.startswith('_'):
continue
if callable(getattr(module, attr)):
functions[mod + '.' + attr] = getattr(module, attr)
functions['sys.list_functions'] = lambda: functions.keys()
functions['sys.doc'] = lambda: self.__get_docs()
functions['sys.reload_functions'] = lambda: self.reload_functions()
print functions
return functions
def __get_docs(self):
'''
Return a dict containing all of the doc strings in the functions dict
'''
docs = {}
for fun in self.functions:
docs[fun] = self.functions[fun].__doc__
return docs
def _handle_payload(self, payload):
'''
Takes a payload from the master publisher and does whatever the
@ -139,6 +154,12 @@ class Minion(object):
'''
return bool(re.match(tgt, self.opts['hostname']))
def _list_match(self, tgt):
'''
Determines if this host is on the list
'''
return bool(tgt.count(self.opts['hostname']))
def _return_pub(self, ret):
'''
Returnt the data from the executed command to the master server
@ -155,6 +176,12 @@ class Minion(object):
socket.send_pyobj(payload)
return socket.recv()
def reload_functions(self):
'''
Reload the functions dict for this minion, reading in any new functions
'''
self.functions = self.__load_functions()
def authenticate(self):
'''
Authenticate with the master, this method breaks the functional

View file

@ -10,7 +10,10 @@ import tempfile
def run(cmd):
'''
Execute the passed command and return the output
Execute the passed command and return the output as a string
CLI Example:
salt '*' cmd.run "ls -l | grep foo | awk '{print $2}'"
'''
return subprocess.Popen(cmd,
shell=True,
@ -20,6 +23,9 @@ def run(cmd):
def run_stdout(cmd):
'''
Execute a command, and only return the standard out
CLI Example:
salt '*' cmd.run "ls -l | grep foo | awk '{print $2}'"
'''
return subprocess.Popen(cmd,
shell=True,
@ -28,6 +34,9 @@ def run_stdout(cmd):
def run_stderr(cmd):
'''
Executa a command and only return the
CLI Example:
salt '*' cmd.run "ls -l | grep foo | awk '{print $2}'"
'''
return subprocess.Popen(cmd,
shell=True,

View file

@ -7,6 +7,9 @@ def list_pkgs():
'''
List the packages currently installed in a dict:
{'<package_name>': '<version>'}
CLI Example:
salt '*' pacman.list_pkgs
'''
cmd = 'pacman -Q'
ret = {}
@ -24,6 +27,9 @@ def refresh_db():
'''
Just run a pacman -Sy, return a dict:
{'<database name>': Bool}
CLI Example:
salt '*' pacman.refresh_db
'''
cmd = 'pacman -Sy'
ret = {}
@ -49,6 +55,9 @@ def install(pkg, refresh=False):
Return a dict containing the new package names and versions:
{'<package>': {'old': '<old-version>',
'new': '<new-version>']}
CLI Example:
salt '*' pacman.install <package name>
'''
old = list_pkgs()
cmd = 'pacman -S --noprogressbar --noconfirm ' + pkg
@ -79,6 +88,9 @@ def upgrade():
Return a dict containing the new package names and versions:
{'<package>': {'old': '<old-version>',
'new': '<new-version>']}
CLI Example:
salt '*' pacman.upgrade
'''
old = list_pkgs()
cmd = 'pacman -Syu --noprogressbar --noconfirm '

View file

@ -6,6 +6,9 @@ import subprocess
def uptime():
'''
Return the uptime for this minion
CLI Example:
salt '*' stats.uptime
'''
return subprocess.Popen(['uptime'],
stdout=subprocess.PIPE).communicate()[0]

View file

@ -5,6 +5,9 @@ Module for running arbitrairy tests
def echo(text):
'''
Return a string - used for testing the connection
CLI Example:
salt '*' test.echo 'foo bar baz quo qux'
'''
print 'Echo got called!'
return text
@ -13,5 +16,8 @@ def ping():
'''
Just used to make sure the minion is up and responding
Return True
CLI Example:
salt '*' test.ping
'''
return True