mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 09:23:56 +00:00
Merge remote-tracking branch 'upstream/2014.7' into 2014.7_sam6
Conflicts: salt/daemons/flo/worker.py
This commit is contained in:
commit
8c713a3d82
@ -1,5 +1,5 @@
|
||||
Jinja2
|
||||
msgpack-python > 0.1.13
|
||||
msgpack-python > 0.3
|
||||
PyYAML
|
||||
MarkupSafe
|
||||
requests
|
||||
|
@ -24,7 +24,6 @@ import os
|
||||
import time
|
||||
import copy
|
||||
import logging
|
||||
import zmq
|
||||
import errno
|
||||
from datetime import datetime
|
||||
from salt._compat import string_types
|
||||
@ -44,6 +43,12 @@ from salt.exceptions import (
|
||||
EauthAuthenticationError, SaltInvocationError, SaltReqTimeoutError
|
||||
)
|
||||
|
||||
# Import third party libs
|
||||
try:
|
||||
import zmq
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Try to import range from https://github.com/ytoolshed/range
|
||||
HAS_RANGE = False
|
||||
try:
|
||||
@ -786,17 +791,11 @@ class LocalClient(object):
|
||||
if event is None:
|
||||
event = self.event
|
||||
while True:
|
||||
try:
|
||||
raw = event.get_event_noblock()
|
||||
if raw and raw.get('tag', '').startswith(jid):
|
||||
yield raw
|
||||
else:
|
||||
yield None
|
||||
except zmq.ZMQError as ex:
|
||||
if ex.errno == errno.EAGAIN or ex.errno == errno.EINTR:
|
||||
yield None
|
||||
else:
|
||||
raise
|
||||
raw = event.get_event_noblock()
|
||||
if raw and raw.get('tag', '').startswith(jid):
|
||||
yield raw
|
||||
else:
|
||||
yield None
|
||||
|
||||
def get_iter_returns(
|
||||
self,
|
||||
@ -846,6 +845,9 @@ class LocalClient(object):
|
||||
# iterator for the info of this job
|
||||
jinfo_iter = []
|
||||
jinfo_timeout = time.time() + timeout
|
||||
# are there still minions running the job out there
|
||||
# start as True so that we ping at least once
|
||||
minions_running = True
|
||||
while True:
|
||||
# Process events until timeout is reached or all minions have returned
|
||||
for raw in ret_iter:
|
||||
@ -867,7 +869,7 @@ class LocalClient(object):
|
||||
else:
|
||||
found.add(raw['data']['id'])
|
||||
ret = {raw['data']['id']: {'ret': raw['data']['return']}}
|
||||
if 'out' in raw:
|
||||
if 'out' in raw['data']:
|
||||
ret[raw['data']['id']]['out'] = raw['data']['out']
|
||||
log.debug('jid {0} return from {1}'.format(jid, raw['data']['id']))
|
||||
yield ret
|
||||
@ -886,15 +888,14 @@ class LocalClient(object):
|
||||
break
|
||||
|
||||
# let start the timeouts for all remaining minions
|
||||
missing_minions = minions - found
|
||||
for id_ in missing_minions:
|
||||
for id_ in minions - found:
|
||||
# if we have a new minion in the list, make sure it has a timeout
|
||||
if id_ not in minion_timeouts:
|
||||
minion_timeouts[id_] = time.time() + timeout
|
||||
|
||||
# if we don't have the job info iterator (or its timed out),
|
||||
# lets make it assuming we have more minions to ping for
|
||||
if time.time() > jinfo_timeout and missing_minions:
|
||||
# if the jinfo has timed out and some minions are still running the job
|
||||
# re-do the ping
|
||||
if time.time() > jinfo_timeout and minions_running:
|
||||
# need our own event listener, so we don't clobber the class one
|
||||
event = salt.utils.event.get_event(
|
||||
'master',
|
||||
@ -904,7 +905,9 @@ class LocalClient(object):
|
||||
listen=not self.opts.get('__worker', False))
|
||||
# start listening for new events, before firing off the pings
|
||||
event.connect_pub()
|
||||
# since this is a new ping, no one has responded yet
|
||||
jinfo = self.gather_job_info(jid, tgt, tgt_type)
|
||||
minions_running = False
|
||||
# if we weren't assigned any jid that means the master thinks
|
||||
# we have nothing to send
|
||||
if 'jid' not in jinfo:
|
||||
@ -938,13 +941,15 @@ class LocalClient(object):
|
||||
minions.add(raw['data']['id'])
|
||||
# update this minion's timeout, as long as the job is still running
|
||||
minion_timeouts[raw['data']['id']] = time.time() + timeout
|
||||
# a minion returned, so we know its running somewhere
|
||||
minions_running = True
|
||||
|
||||
# if we have hit gather_job_timeout (after firing the job) AND
|
||||
# if we have hit all minion timeouts, lets call it
|
||||
now = time.time()
|
||||
# if we have finished pinging all the minions
|
||||
done = now > jinfo_timeout
|
||||
# only check minion timeouts if the ping job is all done
|
||||
# if we have finished waiting, and no minions are running the job
|
||||
# then we need to see if each minion has timedout
|
||||
done = (now > jinfo_timeout) and not minions_running
|
||||
if done:
|
||||
# if all minions have timeod out
|
||||
for id_ in minions - found:
|
||||
|
@ -53,9 +53,9 @@ class LocalClient(salt.client.LocalClient):
|
||||
**kwargs)
|
||||
kind = self.opts['__role']
|
||||
if kind == 'master':
|
||||
lanename = 'master' #self.opts.value.get('id', self.main.data.lanename)
|
||||
else: # workers currently are only supported for masters
|
||||
emsg =("Invalid application kind '{0}' for client.".format())
|
||||
lanename = 'master' # self.opts.value.get('id', self.main.data.lanename)
|
||||
else: # workers currently are only supported for masters
|
||||
emsg = ("Invalid application kind '{0}' for client.".format(kind))
|
||||
log.error(emsg + '\n')
|
||||
raise ValueError(emsg)
|
||||
name = 'client' + nacling.uuid(size=18)
|
||||
|
@ -915,7 +915,7 @@ class SaltRaetEventer(ioflo.base.deeding.Deed):
|
||||
Register event requests
|
||||
Iterate over the registered event yards and fire!
|
||||
'''
|
||||
while self.event_req.value: # event subscription requests are msg with routes
|
||||
while self.event_req.value: # event subscription requests are msg with routes
|
||||
self._register_event_yard(
|
||||
self.event_req.value.popleft()
|
||||
)
|
||||
|
@ -118,7 +118,7 @@ class SaltRaetWorkerSetup(ioflo.base.deeding.Deed):
|
||||
if kind == 'master':
|
||||
lanename = 'master' #self.local.data.lanename
|
||||
else: # workers currently are only supported for masters
|
||||
emsg =("Invalid application kind '{0}' for worker.".format())
|
||||
emsg = ("Invalid application kind '{0}' for worker.".format(kind))
|
||||
log.error(emsg + '\n')
|
||||
raise ValueError(emsg)
|
||||
|
||||
|
@ -840,9 +840,7 @@ class LocalClient(Client):
|
||||
if not path:
|
||||
return {}
|
||||
ret = {}
|
||||
with salt.utils.fopen(path, 'rb') as ifile:
|
||||
ret['hsum'] = getattr(hashlib, self.opts['hash_type'])(
|
||||
ifile.read()).hexdigest()
|
||||
ret['hsum'] = salt.utils.get_hash(path, self.opts['hash_type'])
|
||||
ret['hash_type'] = self.opts['hash_type']
|
||||
return ret
|
||||
|
||||
@ -1008,15 +1006,11 @@ class RemoteClient(Client):
|
||||
# Master has prompted a file verification, if the
|
||||
# verification fails, re-download the file. Try 3 times
|
||||
d_tries += 1
|
||||
with salt.utils.fopen(dest, 'rb') as fp_:
|
||||
hsum = getattr(
|
||||
hashlib,
|
||||
data.get('hash_type', 'md5')
|
||||
)(fp_.read()).hexdigest()
|
||||
if hsum != data['hsum']:
|
||||
log.warn('Bad download of file {0}, attempt {1} '
|
||||
'of 3'.format(path, d_tries))
|
||||
continue
|
||||
hsum = salt.utils.get_hash(dest, data.get('hash_type', 'md5'))
|
||||
if hsum != data['hsum']:
|
||||
log.warn('Bad download of file {0}, attempt {1} '
|
||||
'of 3'.format(path, d_tries))
|
||||
continue
|
||||
break
|
||||
if not fn_:
|
||||
with self._cache_loc(data['dest'], saltenv) as cache_dest:
|
||||
|
@ -1284,9 +1284,7 @@ def file_hash(load, fnd):
|
||||
if not os.path.isfile(hashdest):
|
||||
if not os.path.exists(os.path.dirname(hashdest)):
|
||||
os.makedirs(os.path.dirname(hashdest))
|
||||
with salt.utils.fopen(path, 'rb') as fp_:
|
||||
ret['hsum'] = getattr(hashlib, __opts__['hash_type'])(
|
||||
fp_.read()).hexdigest()
|
||||
ret['hsum'] = salt.utils.get_hash(path, __opts__['hash_type'])
|
||||
with salt.utils.fopen(hashdest, 'w+') as fp_:
|
||||
fp_.write(ret['hsum'])
|
||||
return ret
|
||||
|
@ -550,9 +550,7 @@ def file_hash(load, fnd):
|
||||
'{0}.hash.{1}'.format(relpath,
|
||||
__opts__['hash_type']))
|
||||
if not os.path.isfile(hashdest):
|
||||
with salt.utils.fopen(path, 'rb') as fp_:
|
||||
ret['hsum'] = getattr(hashlib, __opts__['hash_type'])(
|
||||
fp_.read()).hexdigest()
|
||||
ret['hsum'] = salt.utils.get_hash(path, __opts__['hash_type'])
|
||||
with salt.utils.fopen(hashdest, 'w+') as fp_:
|
||||
fp_.write(ret['hsum'])
|
||||
return ret
|
||||
|
@ -66,7 +66,6 @@ structure::
|
||||
# Import python libs
|
||||
import datetime
|
||||
import os
|
||||
import hashlib
|
||||
import time
|
||||
import pickle
|
||||
import urllib
|
||||
@ -522,12 +521,10 @@ def _get_file_from_s3(metadata, saltenv, bucket_name, path, cached_file_path):
|
||||
|
||||
if file_etag.find('-') == -1:
|
||||
file_md5 = file_etag
|
||||
cached_file_hash = hashlib.md5()
|
||||
with salt.utils.fopen(cached_file_path, 'rb') as fp_:
|
||||
cached_file_hash.update(fp_.read())
|
||||
cached_md5 = salt.utils.get_hash(cached_file_path, 'md5')
|
||||
|
||||
# hashes match we have a cache hit
|
||||
if cached_file_hash.hexdigest() == file_md5:
|
||||
if cached_md5 == file_md5:
|
||||
return
|
||||
else:
|
||||
cached_file_stat = os.stat(cached_file_path)
|
||||
|
@ -12,7 +12,6 @@ import shutil
|
||||
import fnmatch
|
||||
import hashlib
|
||||
import json
|
||||
import msgpack
|
||||
import logging
|
||||
|
||||
# Import salt libs
|
||||
@ -22,8 +21,15 @@ import salt.utils.event
|
||||
import salt.daemons.masterapi
|
||||
from salt.utils.event import tagify
|
||||
|
||||
# Import third party libs
|
||||
try:
|
||||
import msgpack
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class KeyCLI(object):
|
||||
'''
|
||||
Manage key CLI operations
|
||||
|
@ -250,17 +250,15 @@ def _run(cmd,
|
||||
py_code = 'import os, json;' \
|
||||
'print(json.dumps(os.environ.__dict__))'
|
||||
if __grains__['os'] in ['MacOS', 'Darwin']:
|
||||
env_cmd = ('sudo -i -u {1} -- "{2}"'
|
||||
).format(shell, runas, sys.executable)
|
||||
env_cmd = ('sudo', '-i', '-u', runas, '--',
|
||||
sys.executable)
|
||||
elif __grains__['os'] in ['FreeBSD']:
|
||||
env_cmd = ('su - {1} -c "{0} -c \'{2}\'"'
|
||||
).format(shell, runas, sys.executable)
|
||||
env_cmd = ('su', '-', runas, '-c',
|
||||
"{0} -c {1}".format(shell, sys.executable))
|
||||
else:
|
||||
env_cmd = ('su -s {0} - {1} -c "{2}"'
|
||||
).format(shell, runas, sys.executable)
|
||||
env_cmd = ('su', '-s', shell, '-', runas, '-c', sys.executable)
|
||||
env_json = subprocess.Popen(
|
||||
env_cmd,
|
||||
shell=python_shell,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE
|
||||
).communicate(py_code)[0]
|
||||
|
@ -83,7 +83,7 @@ def fire(data, tag):
|
||||
salt '*' event.fire '{"data":"my event data"}' 'tag'
|
||||
'''
|
||||
try:
|
||||
event = salt.utils.event.get_event('minion', # was __opts__['id']
|
||||
event = salt.utils.event.get_event('minion', # was __opts__['id']
|
||||
sock_dir=__opts__['sock_dir'],
|
||||
transport=__opts__['transport'],
|
||||
opts=__opts__,
|
||||
|
@ -9,7 +9,6 @@ Interact with virtual machine images via libguestfs
|
||||
import os
|
||||
import tempfile
|
||||
import hashlib
|
||||
import random
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils
|
||||
@ -49,7 +48,7 @@ def mount(location, access='rw'):
|
||||
if os.listdir(root):
|
||||
# Stuf is in there, don't use it
|
||||
hash_type = getattr(hashlib, __opts__.get('hash_type', 'md5'))
|
||||
rand = hash_type(str(random.randint(1, 1000000))).hexdigest()
|
||||
rand = hash_type(os.urandom(32)).hexdigest()
|
||||
root = os.path.join(
|
||||
tempfile.gettempdir(),
|
||||
'guest',
|
||||
|
@ -144,7 +144,7 @@ def db_create(name, user=None, password=None, host=None, port=None):
|
||||
salt '*' influxdb.db_create <name>
|
||||
salt '*' influxdb.db_create <name> <user> <password> <host> <port>
|
||||
"""
|
||||
if db_exists(name):
|
||||
if db_exists(name, user, password, host, port):
|
||||
log.info('DB {0!r} already exists'.format(name))
|
||||
return False
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
@ -177,16 +177,19 @@ def db_remove(name, user=None, password=None, host=None, port=None):
|
||||
salt '*' influxdb.db_remove <name>
|
||||
salt '*' influxdb.db_remove <name> <user> <password> <host> <port>
|
||||
"""
|
||||
if not db_exists(name):
|
||||
if not db_exists(name, user, password, host, port):
|
||||
log.info('DB {0!r} does not exist'.format(name))
|
||||
return False
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
return client.delete_database(name)
|
||||
|
||||
|
||||
def user_list(database, user=None, password=None, host=None, port=None):
|
||||
def user_list(database=None, user=None, password=None, host=None, port=None):
|
||||
"""
|
||||
List users of a InfluxDB database
|
||||
List cluster admins or database users.
|
||||
|
||||
If a database is specified: it will return database users list.
|
||||
If a database is not specified: it will return cluster admins list.
|
||||
|
||||
database
|
||||
The database to list the users from
|
||||
@ -207,18 +210,24 @@ def user_list(database, user=None, password=None, host=None, port=None):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' influxdb.user_list
|
||||
salt '*' influxdb.user_list <database>
|
||||
salt '*' influxdb.user_list <database> <user> <password> <host> <port>
|
||||
"""
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
client.switch_db(database)
|
||||
return client.get_database_users()
|
||||
if database:
|
||||
client.switch_db(database)
|
||||
return client.get_database_users()
|
||||
return client.get_list_cluster_admins()
|
||||
|
||||
|
||||
def user_exists(
|
||||
name, database, user=None, password=None, host=None, port=None):
|
||||
name, database=None, user=None, password=None, host=None, port=None):
|
||||
'''
|
||||
Checks if a user exists for a InfluxDB database
|
||||
Checks if a cluster admin or database user exists.
|
||||
|
||||
If a database is specified: it will check for database user existence.
|
||||
If a database is not specified: it will check for cluster admin existence.
|
||||
|
||||
name
|
||||
User name
|
||||
@ -242,6 +251,7 @@ def user_exists(
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' influxdb.user_exists <name>
|
||||
salt '*' influxdb.user_exists <name> <database>
|
||||
salt '*' influxdb.user_exists <name> <database> <user> <password> <host> <port>
|
||||
'''
|
||||
@ -251,10 +261,13 @@ def user_exists(
|
||||
return name in [u['name'] for u in users]
|
||||
|
||||
|
||||
def user_create(name, passwd, database, user=None, password=None, host=None,
|
||||
port=None):
|
||||
def user_create(name, passwd, database=None, user=None, password=None,
|
||||
host=None, port=None):
|
||||
"""
|
||||
Create a InfluxDB user for a specific database
|
||||
Create a cluster admin or a database user.
|
||||
|
||||
If a database is specified: it will create database user.
|
||||
If a database is not specified: it will create a cluster admin.
|
||||
|
||||
name
|
||||
User name for the new user to create
|
||||
@ -281,24 +294,33 @@ def user_create(name, passwd, database, user=None, password=None, host=None,
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' influxdb.user_create <name> <passwd>
|
||||
salt '*' influxdb.user_create <name> <passwd> <database>
|
||||
salt '*' influxdb.user_create <name> <passwd> <database> <user> <password> <host> <port>
|
||||
"""
|
||||
if user_exists(name, database):
|
||||
log.info('User {0!r} already exists for DB {0!r}'.format(
|
||||
name, database))
|
||||
if user_exists(name, database, user, password, host, port):
|
||||
if database:
|
||||
log.info('User {0!r} already exists for DB {0!r}'.format(
|
||||
name, database))
|
||||
else:
|
||||
log.info('Cluster admin {0!r} already exists'.format(name))
|
||||
return False
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
client.switch_db(database)
|
||||
return client.add_database_user(name, passwd)
|
||||
if database:
|
||||
client.switch_db(database)
|
||||
return client.add_database_user(name, passwd)
|
||||
return client.add_cluster_admin(name, passwd)
|
||||
|
||||
|
||||
def user_chpass(dbuser, passwd, database, user=None, password=None, host=None,
|
||||
port=None):
|
||||
def user_chpass(name, passwd, database=None, user=None, password=None,
|
||||
host=None, port=None):
|
||||
"""
|
||||
Change password for a InfluxDB database user
|
||||
Change password for a cluster admin or a database user.
|
||||
|
||||
dbuser
|
||||
If a database is specified: it will update database user password.
|
||||
If a database is not specified: it will update cluster admin password.
|
||||
|
||||
name
|
||||
User name for whom to change the password
|
||||
|
||||
passwd
|
||||
@ -323,22 +345,31 @@ def user_chpass(dbuser, passwd, database, user=None, password=None, host=None,
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' influxdb.user_chpass <dbuser> <passwd> <database>
|
||||
salt '*' influxdb.user_chpass <dbuser> <passwd> <database> <user> <password> <host> <port>
|
||||
salt '*' influxdb.user_chpass <name> <passwd>
|
||||
salt '*' influxdb.user_chpass <name> <passwd> <database>
|
||||
salt '*' influxdb.user_chpass <name> <passwd> <database> <user> <password> <host> <port>
|
||||
"""
|
||||
if not user_exists(dbuser, database):
|
||||
log.info('User {0!r} does not exist for DB {0!r}'.format(
|
||||
dbuser, database))
|
||||
if not user_exists(name, database, user, password, host, port):
|
||||
if database:
|
||||
log.info('User {0!r} does not exist for DB {0!r}'.format(
|
||||
name, database))
|
||||
else:
|
||||
log.info('Cluster admin {0!r} does not exist'.format(name))
|
||||
return False
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
client.switch_db(database)
|
||||
return client.update_database_user_password(dbuser, passwd)
|
||||
if database:
|
||||
client.switch_db(database)
|
||||
return client.update_database_user_password(name, passwd)
|
||||
return client.update_cluster_admin_password(name, passwd)
|
||||
|
||||
|
||||
def user_remove(name, database, user=None, password=None, host=None,
|
||||
def user_remove(name, database=None, user=None, password=None, host=None,
|
||||
port=None):
|
||||
"""
|
||||
Remove a InfluxDB database user
|
||||
Remove a cluster admin or a database user.
|
||||
|
||||
If a database is specified: it will remove the database user.
|
||||
If a database is not specified: it will remove the cluster admin.
|
||||
|
||||
name
|
||||
User name to remove
|
||||
@ -365,16 +396,22 @@ def user_remove(name, database, user=None, password=None, host=None,
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' influxdb.user_remove <name>
|
||||
salt '*' influxdb.user_remove <name> <database>
|
||||
salt '*' influxdb.user_remove <name> <database> <user> <password> <host> <port>
|
||||
"""
|
||||
if not user_exists(name, database):
|
||||
log.info('User {0!r} does not exist for DB {0!r}'.format(
|
||||
name, database))
|
||||
if not user_exists(name, database, user, password, host, port):
|
||||
if database:
|
||||
log.info('User {0!r} does not exist for DB {0!r}'.format(
|
||||
name, database))
|
||||
else:
|
||||
log.info('Cluster admin {0!r} does not exist'.format(name))
|
||||
return False
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
client.switch_db(database)
|
||||
return client.delete_database_user(user)
|
||||
if database:
|
||||
client.switch_db(database)
|
||||
return client.delete_database_user(user)
|
||||
return client.delete_cluster_admin(user)
|
||||
|
||||
|
||||
def query(database, query, time_precision='s', chunked=False, user=None,
|
||||
|
@ -280,6 +280,9 @@ def _connect(**kwargs):
|
||||
# Ensure MySQldb knows the format we use for queries with arguments
|
||||
MySQLdb.paramstyle = 'pyformat'
|
||||
|
||||
if connargs.get('passwd', True) is None: # If present but set to None. (Extreme edge case.)
|
||||
log.warning('MySQL password of None found. Attempting passwordless login.')
|
||||
connargs.pop('passwd')
|
||||
try:
|
||||
dbc = MySQLdb.connect(**connargs)
|
||||
except MySQLdb.OperationalError as exc:
|
||||
|
@ -9,7 +9,6 @@ minion.
|
||||
|
||||
# Import python libs
|
||||
import os
|
||||
import hashlib
|
||||
import shutil
|
||||
import signal
|
||||
import logging
|
||||
@ -112,14 +111,10 @@ def _sync(form, saltenv=None):
|
||||
log.info('Copying {0!r} to {1!r}'.format(fn_, dest))
|
||||
if os.path.isfile(dest):
|
||||
# The file is present, if the sum differs replace it
|
||||
hash_type = getattr(hashlib, __opts__.get('hash_type', 'md5'))
|
||||
srch = hash_type(
|
||||
salt.utils.fopen(fn_, 'r').read()
|
||||
).hexdigest()
|
||||
dsth = hash_type(
|
||||
salt.utils.fopen(dest, 'r').read()
|
||||
).hexdigest()
|
||||
if srch != dsth:
|
||||
hash_type = __opts__.get('hash_type', 'md5')
|
||||
src_digest = salt.utils.get_hash(fn_, hash_type)
|
||||
dst_digest = salt.utils.get_hash(dest, hash_type)
|
||||
if src_digest != dst_digest:
|
||||
# The downloaded file differs, replace!
|
||||
shutil.copyfile(fn_, dest)
|
||||
ret.append('{0}.{1}'.format(form, relname))
|
||||
|
@ -5,7 +5,6 @@ Module for managing timezone on POSIX-like systems.
|
||||
|
||||
# Import python libs
|
||||
import os
|
||||
import hashlib
|
||||
import logging
|
||||
import re
|
||||
|
||||
@ -164,17 +163,15 @@ def zone_compare(timezone):
|
||||
if not os.path.exists(tzfile):
|
||||
return 'Error: {0} does not exist.'.format(tzfile)
|
||||
|
||||
hash_type = getattr(hashlib, __opts__.get('hash_type', 'md5'))
|
||||
hash_type = __opts__.get('hash_type', 'md5')
|
||||
|
||||
try:
|
||||
with salt.utils.fopen(zonepath, 'r') as fp_:
|
||||
usrzone = hash_type(fp_.read()).hexdigest()
|
||||
usrzone = salt.utils.get_hash(zonepath, hash_type)
|
||||
except IOError as exc:
|
||||
raise SaltInvocationError('Invalid timezone {0!r}'.format(timezone))
|
||||
|
||||
try:
|
||||
with salt.utils.fopen(tzfile, 'r') as fp_:
|
||||
etczone = hash_type(fp_.read()).hexdigest()
|
||||
etczone = salt.utils.get_hash(tzfile, hash_type)
|
||||
except IOError as exc:
|
||||
raise CommandExecutionError(
|
||||
'Problem reading timezone file {0}: {1}'
|
||||
|
@ -384,7 +384,7 @@ class Pillar(object):
|
||||
sls, exc
|
||||
)
|
||||
log.critical(msg)
|
||||
errors.append(msg)
|
||||
errors.append('Rendering SLS \'{0}\' failed. Please see master log for details.'.format(sls))
|
||||
mods.add(sls)
|
||||
nstate = None
|
||||
if state:
|
||||
|
@ -14,7 +14,9 @@ import json
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, command):
|
||||
def ext_pillar(minion_id, # pylint: disable=W0613
|
||||
pillar, # pylint: disable=W0613
|
||||
command):
|
||||
'''
|
||||
Execute a command and read the output as JSON
|
||||
'''
|
||||
|
@ -16,7 +16,9 @@ import yaml
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, command):
|
||||
def ext_pillar(minion_id, # pylint: disable=W0613
|
||||
pillar, # pylint: disable=W0613
|
||||
command):
|
||||
'''
|
||||
Execute a command and read the output as YAML
|
||||
'''
|
||||
|
@ -19,7 +19,9 @@ from salt.utils.serializers.yamlex import deserialize
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, command):
|
||||
def ext_pillar(minion_id, # pylint: disable=W0613
|
||||
pillar, # pylint: disable=W0613
|
||||
command):
|
||||
'''
|
||||
Execute a command and read the output as YAMLEX
|
||||
'''
|
||||
|
@ -40,7 +40,10 @@ __opts__ = {'cobbler.url': 'http://localhost/cobbler_api',
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, key=None, only=()):
|
||||
def ext_pillar(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
key=None,
|
||||
only=()):
|
||||
'''
|
||||
Read pillar data from Cobbler via its API.
|
||||
'''
|
||||
|
@ -114,16 +114,16 @@ def __virtual__():
|
||||
return True
|
||||
|
||||
|
||||
def ext_pillar(minion_id,
|
||||
pillar,
|
||||
def ext_pillar(minion_id, # pylint: disable=W0613
|
||||
pillar, # pylint: disable=W0613
|
||||
pillar_name,
|
||||
project_path,
|
||||
settings_module,
|
||||
django_app,
|
||||
env=None,
|
||||
env_file=None,
|
||||
*args,
|
||||
**kwargs):
|
||||
*args, # pylint: disable=W0613
|
||||
**kwargs): # pylint: disable=W0613
|
||||
'''
|
||||
Connect to a Django database through the ORM and retrieve model fields
|
||||
|
||||
|
@ -82,7 +82,9 @@ def __virtual__():
|
||||
return __virtualname__ if HAS_LIBS else False
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, conf): # pylint: disable=W0613
|
||||
def ext_pillar(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
conf):
|
||||
'''
|
||||
Check etcd for all data
|
||||
'''
|
||||
|
@ -56,7 +56,10 @@ __opts__ = {'foreman.url': 'http://foreman/api',
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, key=None, only=()):
|
||||
def ext_pillar(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
key=None,
|
||||
only=()):
|
||||
'''
|
||||
Read pillar data from Foreman via its API.
|
||||
'''
|
||||
|
@ -25,7 +25,9 @@ def __virtual__():
|
||||
return 'hiera' if salt.utils.which('hiera') else False
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, conf):
|
||||
def ext_pillar(minion_id, # pylint: disable=W0613
|
||||
pillar, # pylint: disable=W0613
|
||||
conf):
|
||||
'''
|
||||
Execute hiera and return the data
|
||||
'''
|
||||
|
@ -14,7 +14,9 @@ import subprocess
|
||||
import salt.utils
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, command):
|
||||
def ext_pillar(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
command): # pylint: disable=W0613
|
||||
'''
|
||||
Read in the generated libvirt keys
|
||||
'''
|
||||
|
@ -84,7 +84,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ext_pillar(minion_id,
|
||||
pillar,
|
||||
pillar, # pylint: disable=W0613
|
||||
collection='pillar',
|
||||
id_field='_id',
|
||||
re_pattern=None,
|
||||
|
@ -439,7 +439,10 @@ class merger(object):
|
||||
d[k] = [d[k]]
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, *args, **kwargs):
|
||||
def ext_pillar(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
*args,
|
||||
**kwargs):
|
||||
'''
|
||||
Execute queries, merge and return as a dict
|
||||
'''
|
||||
|
@ -150,7 +150,9 @@ def _do_search(conf):
|
||||
return result
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, config_file):
|
||||
def ext_pillar(minion_id, # pylint: disable=W0613
|
||||
pillar, # pylint: disable=W0613
|
||||
config_file):
|
||||
'''
|
||||
Execute LDAP searches and return the aggregated data
|
||||
'''
|
||||
|
@ -16,7 +16,9 @@ import yaml
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, command):
|
||||
def ext_pillar(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
command):
|
||||
'''
|
||||
Execute an unmodified puppet_node_classifier and read the output as YAML
|
||||
'''
|
||||
|
@ -56,7 +56,9 @@ def ext_pillar(minion_id, pillar, function, **kwargs):
|
||||
return globals()[function](minion_id, pillar, **kwargs)
|
||||
|
||||
|
||||
def key_value(minion_id, pillar, pillar_key='redis_pillar'):
|
||||
def key_value(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
pillar_key='redis_pillar'):
|
||||
'''
|
||||
Looks for key in redis matching minion_id, returns a structure based on the
|
||||
data type of the redis key. String for string type, dict for hash type and
|
||||
@ -89,7 +91,9 @@ def key_value(minion_id, pillar, pillar_key='redis_pillar'):
|
||||
return {}
|
||||
|
||||
|
||||
def key_json(minion_id, pillar, pillar_key=None):
|
||||
def key_json(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
pillar_key=None):
|
||||
'''
|
||||
Pulls a string from redis and deserializes it from json. Deserialized
|
||||
dictionary data loaded directly into top level if pillar_key is not set.
|
||||
|
@ -62,7 +62,6 @@ Multiple environment mode must have this bucket structure:
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
import hashlib
|
||||
import pickle
|
||||
import urllib
|
||||
from copy import deepcopy
|
||||
@ -88,8 +87,15 @@ class S3Credentials(object):
|
||||
self.verify_ssl = verify_ssl
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, bucket, key, keyid, verify_ssl,
|
||||
multiple_env=False, environment='base', service_url=None):
|
||||
def ext_pillar(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
bucket,
|
||||
key,
|
||||
keyid,
|
||||
verify_ssl,
|
||||
multiple_env=False,
|
||||
environment='base',
|
||||
service_url=None):
|
||||
'''
|
||||
Execute a command and read the output as YAML
|
||||
'''
|
||||
@ -330,12 +336,10 @@ def _get_file_from_s3(creds, metadata, saltenv, bucket, path,
|
||||
file_md5 = filter(str.isalnum, file_meta['ETag']) \
|
||||
if file_meta else None
|
||||
|
||||
cached_file_hash = hashlib.md5()
|
||||
with salt.utils.fopen(cached_file_path, 'rb') as fp_:
|
||||
cached_file_hash.update(fp_.read())
|
||||
cached_md5 = salt.utils.get_hash(cached_file_path, 'md5')
|
||||
|
||||
# hashes match we have a cache hit
|
||||
if cached_file_hash.hexdigest() == file_md5:
|
||||
if cached_md5 == file_md5:
|
||||
return
|
||||
|
||||
# ... or get the file from S3
|
||||
|
@ -153,7 +153,9 @@ def _extract_key_val(kv, delim='='):
|
||||
return key, val
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, repo_string):
|
||||
def ext_pillar(minion_id,
|
||||
pillar, # pylint: disable=W0613
|
||||
repo_string):
|
||||
'''
|
||||
Execute a command and read the output as YAML
|
||||
'''
|
||||
|
@ -174,7 +174,18 @@ class RunnerClient(mixins.SyncClientMixin, mixins.AsyncClientMixin, object):
|
||||
self.opts['sock_dir'],
|
||||
self.opts['transport'],
|
||||
opts=self.opts)
|
||||
job = self.master_call(**low)
|
||||
|
||||
# The master_call function here has a different function signature than
|
||||
# on WheelClient. So extract all the eauth keys and the fun key and
|
||||
# assume everything else is a kwarg to pass along to the runner
|
||||
# function to be called.
|
||||
auth_creds = dict([(i, low.pop(i))
|
||||
for i in ['username', 'password', 'eauth', 'token'] if i in low])
|
||||
reformatted_low = {'fun': low.pop('fun')}
|
||||
reformatted_low.update(auth_creds)
|
||||
reformatted_low['kwarg'] = low
|
||||
|
||||
job = self.master_call(**reformatted_low)
|
||||
ret_tag = tagify('ret', base=job['tag'])
|
||||
|
||||
timelimit = time.time() + (timeout or 300)
|
||||
|
10
salt/runners/test.py
Normal file
10
salt/runners/test.py
Normal file
@ -0,0 +1,10 @@
|
||||
def arg(*args, **kwargs):
|
||||
'''
|
||||
Output the given args and kwargs
|
||||
'''
|
||||
ret = {
|
||||
'args': args,
|
||||
'kwargs': kwargs,
|
||||
}
|
||||
print ret
|
||||
return ret
|
@ -10,10 +10,10 @@ Management of InfluxDB users
|
||||
'''
|
||||
|
||||
|
||||
def present(name, passwd, database, user=None, password=None, host=None,
|
||||
def present(name, passwd, database=None, user=None, password=None, host=None,
|
||||
port=None):
|
||||
'''
|
||||
Ensure that the user is present
|
||||
Ensure that the cluster admin or database user is present.
|
||||
|
||||
name
|
||||
The name of the user to manage
|
||||
@ -43,7 +43,7 @@ def present(name, passwd, database, user=None, password=None, host=None,
|
||||
'comment': ''}
|
||||
|
||||
# check if db does not exist
|
||||
if not __salt__['influxdb.db_exists'](
|
||||
if database and not __salt__['influxdb.db_exists'](
|
||||
database, user, password, host, port):
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Database {0} does not exist'.format(database)
|
||||
@ -73,9 +73,10 @@ def present(name, passwd, database, user=None, password=None, host=None,
|
||||
return ret
|
||||
|
||||
|
||||
def absent(name, database, user=None, password=None, host=None, port=None):
|
||||
def absent(name, database=None, user=None, password=None, host=None,
|
||||
port=None):
|
||||
'''
|
||||
Ensure that the named user is absent
|
||||
Ensure that the named cluster admin or database user is absent.
|
||||
|
||||
name
|
||||
The name of the user to remove
|
||||
|
@ -88,7 +88,7 @@ class RAETChannel(Channel):
|
||||
not already setup such as in salt-call to communicate to-from the minion
|
||||
|
||||
'''
|
||||
kind = self.opts.get('__role', '') # application kind 'master', 'minion', etc
|
||||
kind = self.opts.get('__role', '') # application kind 'master', 'minion', etc
|
||||
if not kind:
|
||||
emsg = ("Missing opts['__role']. required to setup RAETChannel.")
|
||||
log.error(emsg + "\n")
|
||||
@ -101,14 +101,13 @@ class RAETChannel(Channel):
|
||||
emsg = ("Missing opts['id']. required to setup RAETChannel.")
|
||||
log.error(emsg + "\n")
|
||||
raise ValueError(emsg)
|
||||
lanename = role # add kind later
|
||||
lanename = role # add kind later
|
||||
else:
|
||||
emsg = ("Unsupported application kind '{0}' for RAETChannel "
|
||||
"Raet.".format(self.node))
|
||||
log.error(emsg + '\n')
|
||||
raise ValueError(emsg)
|
||||
|
||||
|
||||
mid = self.opts.get('id', 'master')
|
||||
uid = nacling.uuid(size=18)
|
||||
name = 'channel' + uid
|
||||
|
@ -82,7 +82,6 @@ the following:
|
||||
|
||||
# Import python libs
|
||||
from __future__ import print_function
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
@ -498,13 +497,8 @@ class PrintOption(Option):
|
||||
result.append(gid)
|
||||
elif arg == 'md5':
|
||||
if stat.S_ISREG(fstat[stat.ST_MODE]):
|
||||
with salt.utils.fopen(fullpath, 'rb') as ifile:
|
||||
buf = ifile.read(8192)
|
||||
md5hash = hashlib.md5()
|
||||
while buf:
|
||||
md5hash.update(buf)
|
||||
buf = ifile.read(8192)
|
||||
result.append(md5hash.hexdigest())
|
||||
md5digest = salt.utils.get_hash(fullpath, 'md5')
|
||||
result.append(md5digest)
|
||||
else:
|
||||
result.append('')
|
||||
|
||||
|
@ -32,7 +32,7 @@ class SaltEvent(object):
|
||||
'''
|
||||
Set up the stack and remote yard
|
||||
'''
|
||||
self.node = node # application kind 'master', 'minion', 'syndic', 'call' etc
|
||||
self.node = node # application kind 'master', 'minion', 'syndic', 'call' etc
|
||||
self.sock_dir = sock_dir
|
||||
self.listen = listen
|
||||
if opts is None:
|
||||
@ -44,14 +44,14 @@ class SaltEvent(object):
|
||||
if self.node == 'master':
|
||||
lanename = 'master'
|
||||
if self.opts:
|
||||
kind = self.opts.get('__role', '') # opts optional for master
|
||||
kind = self.opts.get('__role', '') # opts optional for master
|
||||
if kind and kind != self.node:
|
||||
emsg = ("Mismatch between node '{}' and kind '{}' in setup "
|
||||
"of SaltEvent on Raet.".format(self.node, kind))
|
||||
emsg = ("Mismatch between node '{0}' and kind '{1}' in setup "
|
||||
"of SaltEvent on Raet.".format(self.node, kind))
|
||||
log.error(emsg + '\n')
|
||||
raise ValueError(emsg)
|
||||
elif self.node == 'minion':
|
||||
role = self.opts.get('id', '') #opts required for minion
|
||||
role = self.opts.get('id', '') # opts required for minion
|
||||
if not role:
|
||||
emsg = ("Missing opts['id'] required by SaltEvent on Raet with "
|
||||
"node kind {0}.".format(self.node))
|
||||
@ -59,11 +59,11 @@ class SaltEvent(object):
|
||||
raise ValueError(emsg)
|
||||
kind = self.opts.get('__role', '')
|
||||
if kind != self.node:
|
||||
emsg = ("Mismatch between node '{}' and kind '{}' in setup "
|
||||
emsg = ("Mismatch between node '{0}' and kind '{1}' in setup "
|
||||
"of SaltEvent on Raet.".format(self.node, kind))
|
||||
log.error(emsg + '\n')
|
||||
raise ValueError(emsg)
|
||||
lanename = role # add '_minion'
|
||||
lanename = role # add '_minion'
|
||||
else:
|
||||
emsg = ("Unsupported application node kind '{0}' for SaltEvent "
|
||||
"Raet.".format(self.node))
|
||||
|
@ -55,6 +55,19 @@ def wrap_tmpl_func(render_str):
|
||||
# We want explicit context to overwrite the **kws
|
||||
kws.update(context)
|
||||
context = kws
|
||||
assert 'opts' in context
|
||||
assert 'saltenv' in context
|
||||
|
||||
if 'sls' in context:
|
||||
slspath = context['sls'].replace('.', '/')
|
||||
if tmplpath is not None:
|
||||
context['tplpath'] = tmplpath
|
||||
if not tmplpath.lower().replace('\\', '/').endswith('/init.sls'):
|
||||
slspath = os.path.dirname(slspath)
|
||||
context['slsdotpath'] = slspath.replace('/', '.')
|
||||
context['slscolonpath'] = slspath.replace('/', ':')
|
||||
context['sls_path'] = slspath.replace('/', '_')
|
||||
context['slspath'] = slspath
|
||||
|
||||
if isinstance(tmplsrc, string_types):
|
||||
if from_str:
|
||||
|
@ -6,7 +6,6 @@ Wheel system wrapper for key system
|
||||
# Import python libs
|
||||
import os
|
||||
import hashlib
|
||||
import random
|
||||
|
||||
# Import salt libs
|
||||
import salt.key
|
||||
@ -79,7 +78,7 @@ def gen(id_=None, keysize=2048):
|
||||
returned as a dict containing pub and priv keys
|
||||
'''
|
||||
if id_ is None:
|
||||
id_ = hashlib.sha512(str(random.SystemRandom().randint(0, 99999999))).hexdigest()
|
||||
id_ = hashlib.sha512(os.urandom(32)).hexdigest()
|
||||
ret = {'priv': '',
|
||||
'pub': ''}
|
||||
priv = salt.crypt.gen_keys(__opts__['pki_dir'], id_, keysize)
|
||||
|
223
setup.py
223
setup.py
@ -66,6 +66,7 @@ if 'USE_SETUPTOOLS' in os.environ or 'setuptools' in sys.modules:
|
||||
from setuptools import setup
|
||||
from setuptools.command.install import install
|
||||
from setuptools.command.sdist import sdist
|
||||
from setuptools.command.egg_info import egg_info
|
||||
WITH_SETUPTOOLS = True
|
||||
except ImportError:
|
||||
WITH_SETUPTOOLS = False
|
||||
@ -101,6 +102,10 @@ SALT_CLOUD_REQS = os.path.join(os.path.abspath(SETUP_DIRNAME), 'cloud-requiremen
|
||||
SALT_RAET_REQS = os.path.join(os.path.abspath(SETUP_DIRNAME), 'raet-requirements.txt')
|
||||
SALT_SYSPATHS = os.path.join(os.path.abspath(SETUP_DIRNAME), 'salt', 'syspaths.py')
|
||||
|
||||
# Salt SSH Packaging Detection
|
||||
PACKAGED_FOR_SALT_SSH_FILE = os.path.join(os.path.abspath(SETUP_DIRNAME), '.salt-ssh-package')
|
||||
PACKAGED_FOR_SALT_SSH = os.path.isfile(PACKAGED_FOR_SALT_SSH_FILE)
|
||||
|
||||
# pylint: disable=W0122
|
||||
exec(compile(open(SALT_VERSION).read(), SALT_VERSION, 'exec'))
|
||||
exec(compile(open(SALT_SYSPATHS).read(), SALT_SYSPATHS, 'exec'))
|
||||
@ -150,8 +155,67 @@ class WriteSaltVersion(Command):
|
||||
# pylint: enable=E0602
|
||||
|
||||
|
||||
class WriteSaltSshPackaingFile(Command):
|
||||
|
||||
description = 'Write salt\'s ssh packaging file'
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
if not os.path.exists(PACKAGED_FOR_SALT_SSH_FILE):
|
||||
# Write the salt-ssh packaging file
|
||||
if getattr(self.distribution, 'salt_ssh_packaging_file', None) is None:
|
||||
print 'This command is not meant to be called on it\'s own'
|
||||
exit(1)
|
||||
|
||||
# pylint: disable=E0602
|
||||
open(self.distribution.salt_ssh_packaging_file, 'w').write('Packaged for Salt-SSH\n')
|
||||
# pylint: enable=E0602
|
||||
|
||||
|
||||
if WITH_SETUPTOOLS is True:
|
||||
class EggInfo(egg_info):
|
||||
|
||||
def finalize_options(self):
|
||||
if getattr(self.distribution, 'packaged_for_salt_ssh', PACKAGED_FOR_SALT_SSH):
|
||||
self.distribution.metadata.name = 'salt-ssh'
|
||||
egg_info.finalize_options(self)
|
||||
|
||||
|
||||
class Sdist(sdist):
|
||||
user_options = sdist.user_options + [
|
||||
('ssh-packaging', None, 'Prepare the salt-ssh packaging')
|
||||
]
|
||||
boolean_options = sdist.boolean_options + [
|
||||
'ssh-packaging'
|
||||
]
|
||||
|
||||
def initialize_options(self):
|
||||
sdist.initialize_options(self)
|
||||
self.ssh_packaging = PACKAGED_FOR_SALT_SSH
|
||||
|
||||
def finalize_options(self):
|
||||
sdist.finalize_options(self)
|
||||
self.distribution.packaged_for_salt_ssh = self.ssh_packaging
|
||||
|
||||
def make_release_tree(self, base_dir, files):
|
||||
if self.ssh_packaging:
|
||||
self.distribution.salt_ssh_packaging_file = PACKAGED_FOR_SALT_SSH_FILE
|
||||
self.run_command('write-salt-ssh-packaging-file')
|
||||
self.distribution.package_data.pop('salt.daemons.flo', None)
|
||||
self.filelist.files.append(os.path.basename(PACKAGED_FOR_SALT_SSH_FILE))
|
||||
self.distribution.metadata.name = 'salt-ssh'
|
||||
self.distribution.data_files = [('share/man/man1',
|
||||
['doc/man/salt-ssh.1',
|
||||
'doc/man/salt-run.1',
|
||||
'doc/man/salt-call.1',
|
||||
'doc/man/salt-cloud.1']),
|
||||
('share/man/man7', ['doc/man/salt.7'])]
|
||||
|
||||
sdist.make_release_tree(self, base_dir, files)
|
||||
|
||||
# Let's generate salt/_version.py to include in the sdist tarball
|
||||
@ -161,16 +225,21 @@ class Sdist(sdist):
|
||||
)
|
||||
self.run_command('write-salt-version')
|
||||
|
||||
def make_distribution(self):
|
||||
sdist.make_distribution(self)
|
||||
if self.ssh_packaging:
|
||||
os.unlink(PACKAGED_FOR_SALT_SSH_FILE)
|
||||
|
||||
|
||||
class CloudSdist(Sdist):
|
||||
user_options = sdist.user_options + [
|
||||
user_options = Sdist.user_options + [
|
||||
('download-bootstrap-script', None,
|
||||
'Download the latest stable bootstrap-salt.sh script. This '
|
||||
'can also be triggered by having `DOWNLOAD_BOOTSTRAP_SCRIPT=1` as an '
|
||||
'environment variable.')
|
||||
|
||||
]
|
||||
boolean_options = sdist.boolean_options + [
|
||||
boolean_options = Sdist.boolean_options + [
|
||||
'download-bootstrap-script'
|
||||
]
|
||||
|
||||
@ -268,6 +337,18 @@ class CloudSdist(Sdist):
|
||||
self.filelist.files.pop(
|
||||
self.filelist.files.index(filename)
|
||||
)
|
||||
elif self.distribution.packaged_for_salt_ssh:
|
||||
# Remove un-necessary script from Salt-SSH package
|
||||
for filename in self.filelist.files[:]:
|
||||
if not filename.startswith('scripts/'):
|
||||
continue
|
||||
if filename not in ('scripts/salt-ssh',
|
||||
'scripts/salt-run',
|
||||
'scripts/salt-call',
|
||||
'scripts/salt-cloud'):
|
||||
self.filelist.files.pop(
|
||||
self.filelist.files.index(filename)
|
||||
)
|
||||
return Sdist.write_manifest(self)
|
||||
|
||||
|
||||
@ -405,7 +486,10 @@ class Install(install):
|
||||
# Non setuptools installation
|
||||
self.distribution.install_requires = _parse_requirements_file(SALT_REQS)
|
||||
# pylint: disable=E0602
|
||||
self.salt_transport = 'zeromq'
|
||||
if PACKAGED_FOR_SALT_SSH:
|
||||
self.salt_transport = 'ssh'
|
||||
else:
|
||||
self.salt_transport = 'zeromq'
|
||||
self.salt_root_dir = ROOT_DIR
|
||||
self.salt_config_dir = CONFIG_DIR
|
||||
self.salt_cache_dir = CACHE_DIR
|
||||
@ -420,6 +504,9 @@ class Install(install):
|
||||
|
||||
def finalize_options(self):
|
||||
install.finalize_options(self)
|
||||
if PACKAGED_FOR_SALT_SSH and self.salt_transport != 'ssh':
|
||||
raise DistutilsArgError('The only available transport for salt-ssh is \'ssh\'')
|
||||
|
||||
for optname in ('root_dir', 'config_dir', 'cache_dir', 'sock_dir',
|
||||
'srv_root_dir', 'base_file_roots_dir',
|
||||
'base_pillar_roots_dir', 'base_master_roots_dir',
|
||||
@ -433,19 +520,18 @@ class Install(install):
|
||||
)
|
||||
setattr(self.distribution, 'salt_{0}'.format(optname), optvalue)
|
||||
|
||||
if self.salt_transport not in ('zeromq', 'raet', 'both', 'none'):
|
||||
if self.salt_transport not in ('zeromq', 'raet', 'both', 'ssh', 'none'):
|
||||
raise DistutilsArgError(
|
||||
'The value of --salt-transport needs be \'zeromq\', '
|
||||
'\'raet\', \'both\' or \'none\' not {0!r}'.format(
|
||||
'\'raet\', \'both\' \'ssh\' or \'none\' not {0!r}'.format(
|
||||
self.salt_transport
|
||||
)
|
||||
)
|
||||
elif self.salt_transport == 'none':
|
||||
elif self.salt_transport in ('ssh', 'none'):
|
||||
for requirement in _parse_requirements_file(SALT_ZEROMQ_REQS):
|
||||
if requirement not in self.distribution.install_requires:
|
||||
continue
|
||||
self.distribution.install_requires.remove(requirement)
|
||||
|
||||
elif self.salt_transport in ('raet', 'both'):
|
||||
self.distribution.install_requires.extend(
|
||||
_parse_requirements_file(SALT_RAET_REQS)
|
||||
@ -489,8 +575,11 @@ class InstallLib(install_lib):
|
||||
os.chmod(filename, 0755)
|
||||
# <---- Custom Distutils/Setuptools Commands -------------------------------------------------------------------------
|
||||
|
||||
if PACKAGED_FOR_SALT_SSH:
|
||||
NAME = 'salt-ssh'
|
||||
else:
|
||||
NAME = 'salt'
|
||||
|
||||
NAME = 'salt'
|
||||
VER = __version__ # pylint: disable=E0602
|
||||
DESC = 'Portable, distributed, remote execution and configuration management system'
|
||||
|
||||
@ -506,7 +595,8 @@ SETUP_KWARGS = {'name': NAME,
|
||||
'build': Build,
|
||||
'sdist': Sdist,
|
||||
'install': Install,
|
||||
'write-salt-version': WriteSaltVersion
|
||||
'write-salt-version': WriteSaltVersion,
|
||||
'write-salt-ssh-packaging-file': WriteSaltSshPackaingFile,
|
||||
},
|
||||
'classifiers': ['Programming Language :: Python',
|
||||
'Programming Language :: Cython',
|
||||
@ -598,23 +688,34 @@ SETUP_KWARGS = {'name': NAME,
|
||||
'zip_safe': False
|
||||
}
|
||||
|
||||
if PACKAGED_FOR_SALT_SSH:
|
||||
SETUP_KWARGS['data_files'][0][1].extend([
|
||||
'doc/man/salt-ssh.1',
|
||||
'doc/man/salt-run.1',
|
||||
'doc/man/salt-cloud.1',
|
||||
])
|
||||
|
||||
if IS_WINDOWS_PLATFORM is False:
|
||||
SETUP_KWARGS['cmdclass']['sdist'] = CloudSdist
|
||||
SETUP_KWARGS['cmdclass']['install_lib'] = InstallLib
|
||||
# SETUP_KWARGS['packages'].extend(['salt.cloud',
|
||||
# 'salt.cloud.clouds'])
|
||||
SETUP_KWARGS['package_data']['salt.cloud'] = ['deploy/*.sh']
|
||||
|
||||
SETUP_KWARGS['data_files'][0][1].extend([
|
||||
'doc/man/salt-master.1',
|
||||
'doc/man/salt-key.1',
|
||||
'doc/man/salt.1',
|
||||
'doc/man/salt-api.1',
|
||||
'doc/man/salt-syndic.1',
|
||||
'doc/man/salt-run.1',
|
||||
'doc/man/salt-ssh.1',
|
||||
'doc/man/salt-cloud.1',
|
||||
'doc/man/salt-unity.1',
|
||||
])
|
||||
if PACKAGED_FOR_SALT_SSH is False:
|
||||
SETUP_KWARGS['data_files'][0][1].extend([
|
||||
'doc/man/salt-ssh.1',
|
||||
'doc/man/salt-run.1',
|
||||
'doc/man/salt-cloud.1',
|
||||
])
|
||||
|
||||
|
||||
# bbfreeze explicit includes
|
||||
@ -714,23 +815,41 @@ if HAS_ESKY:
|
||||
SETUP_KWARGS['options'] = OPTIONS
|
||||
|
||||
if WITH_SETUPTOOLS:
|
||||
SETUP_KWARGS['entry_points'] = {
|
||||
'console_scripts': ['salt-call = salt.scripts:salt_call',
|
||||
'salt-cp = salt.scripts:salt_cp',
|
||||
'salt-minion = salt.scripts:salt_minion',
|
||||
]
|
||||
}
|
||||
if IS_WINDOWS_PLATFORM is False:
|
||||
SETUP_KWARGS['entry_points']['console_scripts'].extend([
|
||||
'salt = salt.scripts:salt_main',
|
||||
'salt-api = salt.scripts:salt_api',
|
||||
'salt-cloud = salt.scripts:salt_cloud',
|
||||
'salt-key = salt.scripts:salt_key',
|
||||
'salt-master = salt.scripts:salt_master',
|
||||
'salt-run = salt.scripts:salt_run',
|
||||
SETUP_KWARGS['cmdclass']['egg_info'] = EggInfo
|
||||
if PACKAGED_FOR_SALT_SSH is False:
|
||||
SETUP_KWARGS['entry_points'] = {
|
||||
'console_scripts': ['salt-call = salt.scripts:salt_call',
|
||||
'salt-cp = salt.scripts:salt_cp',
|
||||
'salt-minion = salt.scripts:salt_minion',
|
||||
]
|
||||
}
|
||||
else:
|
||||
SETUP_KWARGS['entry_points'] = {'console_scripts': [
|
||||
'salt-ssh = salt.scripts:salt_ssh',
|
||||
'salt-syndic = salt.scripts:salt_syndic',
|
||||
])
|
||||
'salt-run = salt.scripts:salt_run',
|
||||
'salt-call = salt.scripts:salt_call',
|
||||
'salt-cloud = salt.scripts:salt_cloud',
|
||||
]}
|
||||
if IS_WINDOWS_PLATFORM is False:
|
||||
if PACKAGED_FOR_SALT_SSH:
|
||||
SETUP_KWARGS['entry_points']['console_scripts'].extend([
|
||||
'salt = salt.scripts:salt_main',
|
||||
'salt-api = salt.scripts:salt_api',
|
||||
'salt-key = salt.scripts:salt_key',
|
||||
'salt-master = salt.scripts:salt_master',
|
||||
'salt-syndic = salt.scripts:salt_syndic',
|
||||
])
|
||||
else:
|
||||
SETUP_KWARGS['entry_points']['console_scripts'].extend([
|
||||
'salt = salt.scripts:salt_main',
|
||||
'salt-api = salt.scripts:salt_api',
|
||||
'salt-cloud = salt.scripts:salt_cloud',
|
||||
'salt-key = salt.scripts:salt_key',
|
||||
'salt-master = salt.scripts:salt_master',
|
||||
'salt-run = salt.scripts:salt_run',
|
||||
'salt-ssh = salt.scripts:salt_ssh',
|
||||
'salt-syndic = salt.scripts:salt_syndic',
|
||||
])
|
||||
|
||||
# Required for running the tests suite
|
||||
SETUP_KWARGS['dependency_links'] = [
|
||||
@ -741,23 +860,41 @@ if WITH_SETUPTOOLS:
|
||||
# When WITH_SETUPTOOLS is True, esky builds would fail to include the scripts,
|
||||
# and, if WITH_SETUPTOOLS is True, having scripts and console_scripts defined
|
||||
# does not, apparently, break the build, so, let's have both
|
||||
SETUP_KWARGS['scripts'] = ['scripts/salt-call',
|
||||
'scripts/salt-cp',
|
||||
'scripts/salt-minion',
|
||||
'scripts/salt-unity',
|
||||
]
|
||||
if PACKAGED_FOR_SALT_SSH is False:
|
||||
SETUP_KWARGS['scripts'] = ['scripts/salt-call',
|
||||
'scripts/salt-cp',
|
||||
'scripts/salt-minion',
|
||||
'scripts/salt-unity',
|
||||
]
|
||||
|
||||
if IS_WINDOWS_PLATFORM is False:
|
||||
SETUP_KWARGS['scripts'].extend([
|
||||
'scripts/salt',
|
||||
'scripts/salt-api',
|
||||
'scripts/salt-cloud',
|
||||
'scripts/salt-key',
|
||||
'scripts/salt-master',
|
||||
'scripts/salt-run',
|
||||
'scripts/salt-ssh',
|
||||
'scripts/salt-syndic',
|
||||
])
|
||||
if PACKAGED_FOR_SALT_SSH:
|
||||
SETUP_KWARGS['scripts'] = [
|
||||
'scripts/salt-ssh',
|
||||
'scripts/salt-run',
|
||||
'scripts/salt-call',
|
||||
'scripts/salt-cloud'
|
||||
]
|
||||
else:
|
||||
SETUP_KWARGS['scripts'].extend([
|
||||
'scripts/salt',
|
||||
'scripts/salt-api',
|
||||
'scripts/salt-cloud',
|
||||
'scripts/salt-key',
|
||||
'scripts/salt-master',
|
||||
'scripts/salt-run',
|
||||
'scripts/salt-ssh',
|
||||
'scripts/salt-syndic',
|
||||
])
|
||||
|
||||
|
||||
if PACKAGED_FOR_SALT_SSH:
|
||||
SETUP_KWARGS.pop('extras_require')
|
||||
for requirement in _parse_requirements_file(SALT_ZEROMQ_REQS):
|
||||
if requirement not in SETUP_KWARGS['install_requires']:
|
||||
continue
|
||||
SETUP_KWARGS['install_requires'].remove(requirement)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setup(**SETUP_KWARGS)
|
||||
|
@ -6,6 +6,7 @@ ensure_in_syspath('../../')
|
||||
|
||||
# Import salt libs
|
||||
import integration
|
||||
import os
|
||||
|
||||
|
||||
class StdTest(integration.ModuleCase):
|
||||
@ -36,6 +37,25 @@ class StdTest(integration.ModuleCase):
|
||||
self.assertTrue(ret['minion'])
|
||||
assert num_ret > 0
|
||||
|
||||
# ping a minion that doesnt exist, to make sure that it doesnt hang forever
|
||||
# create fake mininion
|
||||
key_file = os.path.join(self.master_opts['pki_dir'], 'minions', 'footest')
|
||||
# touch the file
|
||||
open(key_file, 'a').close()
|
||||
# ping that minion and ensure it times out
|
||||
try:
|
||||
cmd_iter = self.client.cmd_cli(
|
||||
'footest',
|
||||
'test.ping',
|
||||
)
|
||||
num_ret = 0
|
||||
for ret in cmd_iter:
|
||||
num_ret += 1
|
||||
self.assertTrue(ret['minion'])
|
||||
assert num_ret == 0
|
||||
finally:
|
||||
os.unlink(key_file)
|
||||
|
||||
def test_iter(self):
|
||||
'''
|
||||
test cmd_iter
|
||||
|
@ -77,6 +77,18 @@ class RunnerModuleTest(integration.ClientCase):
|
||||
|
||||
self.runner.cmd_async(low)
|
||||
|
||||
def test_cmd_sync_w_arg(self):
|
||||
low = {
|
||||
'fun': 'test.arg',
|
||||
'foo': 'Foo!',
|
||||
'bar': 'Bar!',
|
||||
}
|
||||
low.update(self.eauth_creds)
|
||||
|
||||
ret = self.runner.cmd_sync(low)
|
||||
self.assertEqual(ret['kwargs']['foo'], 'Foo!')
|
||||
self.assertEqual(ret['kwargs']['bar'], 'Bar!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
|
@ -17,9 +17,7 @@ import re
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import random
|
||||
import shutil
|
||||
import hashlib
|
||||
import argparse
|
||||
import requests
|
||||
import subprocess
|
||||
@ -89,8 +87,7 @@ def generate_vm_name(options):
|
||||
if 'BUILD_NUMBER' in os.environ:
|
||||
random_part = 'BUILD{0:0>6}'.format(os.environ.get('BUILD_NUMBER'))
|
||||
else:
|
||||
random_part = hashlib.md5(
|
||||
str(random.randint(1, 100000000))).hexdigest()[:6]
|
||||
random_part = os.urandom(3).encode('hex')
|
||||
|
||||
return '{0}-{1}-{2}'.format(options.vm_prefix, options.vm_source, random_part)
|
||||
|
||||
|
@ -16,9 +16,7 @@ import re
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import random
|
||||
import shutil
|
||||
import hashlib
|
||||
import optparse
|
||||
import subprocess
|
||||
|
||||
@ -95,8 +93,7 @@ def generate_vm_name(options):
|
||||
if 'BUILD_NUMBER' in os.environ:
|
||||
random_part = 'BUILD{0:0>6}'.format(os.environ.get('BUILD_NUMBER'))
|
||||
else:
|
||||
random_part = hashlib.md5(
|
||||
str(random.randint(1, 100000000))).hexdigest()[:6]
|
||||
random_part = os.urandom(3).encode('hex')
|
||||
|
||||
return '{0}-{1}-{2}'.format(options.vm_prefix, options.platform, random_part)
|
||||
|
||||
|
@ -268,6 +268,17 @@ G:
|
||||
list('ABCDEFG')
|
||||
)
|
||||
|
||||
def test_slsdir(self):
|
||||
result = render_sls('''
|
||||
formula/woot.sls:
|
||||
cmd.run:
|
||||
- name: echo {{ slspath }}
|
||||
- cwd: /
|
||||
''', sls='formula.woot', argline='yaml . jinja')
|
||||
|
||||
r = result['formula/woot.sls']['cmd.run'][0]['name']
|
||||
self.assertEqual(r, 'echo formula/woot')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
|
Loading…
Reference in New Issue
Block a user