Deprecate env usage in favor of saltenv.

This commit is contained in:
Pedro Algarvio 2013-11-09 11:24:43 +00:00
parent 6f6110b743
commit 1f91775927

View File

@ -77,13 +77,23 @@ class Client(object):
return filelist
@contextlib.contextmanager
def _cache_loc(self, path, env='base'):
def _cache_loc(self, path, saltenv='base', env=None):
'''
Return the local location to cache the file, cache dirs will be made
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
dest = os.path.join(self.opts['cachedir'],
'files',
env,
saltenv,
path)
destdir = os.path.dirname(dest)
cumask = os.umask(63)
@ -96,51 +106,87 @@ class Client(object):
yield dest
os.umask(cumask)
def get_file(self, path, dest='', makedirs=False, env='base', gzip=None):
def get_file(self,
path,
dest='',
makedirs=False,
saltenv='base',
gzip=None,
env=None):
'''
Copies a file from the local files or master depending on
implementation
'''
raise NotImplementedError
def file_list_emptydirs(self, env='base', prefix=''):
def file_list_emptydirs(self, saltenv='base', prefix='', env=None):
'''
List the empty dirs
'''
raise NotImplementedError
def cache_file(self, path, env='base'):
def cache_file(self, path, saltenv='base', env=None):
'''
Pull a file down from the file server and store it in the minion
file cache
'''
return self.get_url(path, '', True, env)
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
def cache_files(self, paths, env='base'):
return self.get_url(path, '', True, saltenv)
def cache_files(self, paths, saltenv='base', env=None):
'''
Download a list of files stored on the master and put them in the
minion file cache
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
ret = []
if isinstance(paths, str):
paths = paths.split(',')
for path in paths:
ret.append(self.cache_file(path, env))
ret.append(self.cache_file(path, saltenv))
return ret
def cache_master(self, env='base'):
def cache_master(self, saltenv='base', env=None):
'''
Download and cache all files on a master in a specified environment
'''
ret = []
for path in self.file_list(env):
ret.append(self.cache_file('salt://{0}'.format(path), env))
for path in self.file_list(saltenv):
ret.append(self.cache_file('salt://{0}'.format(path), saltenv))
return ret
def cache_dir(self, path, env='base', include_empty=False):
def cache_dir(self, path, saltenv='base', include_empty=False, env=None):
'''
Download all of the files in a subdir of the master
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
ret = []
path = self._check_proto(path)
# We want to make sure files start with this *directory*, use
@ -150,14 +196,14 @@ class Client(object):
path = path + '/'
log.info(
'Caching directory \'{0}\' for environment \'{1}\''.format(
path, env
'Caching directory {0!r} for environment {1!r}'.format(
path, saltenv
)
)
#go through the list of all files finding ones that are in
#the target directory and caching them
ret.extend([self.cache_file('salt://' + fn_, env)
for fn_ in self.file_list(env)
ret.extend([self.cache_file('salt://' + fn_, saltenv)
for fn_ in self.file_list(saltenv)
if fn_.strip() and fn_.startswith(path)])
if include_empty:
@ -166,16 +212,16 @@ class Client(object):
# preceding it
#separated = string.rsplit(path, '/', 1)
#if len(separated) != 2:
# # No slashes in path. (So all files in env will be copied)
# # No slashes in path. (So all files in saltenv will be copied)
# prefix = ''
#else:
# prefix = separated[0]
dest = salt.utils.path_join(
self.opts['cachedir'],
'files',
env
saltenv
)
for fn_ in self.file_list_emptydirs(env):
for fn_ in self.file_list_emptydirs(saltenv):
if fn_.startswith(path):
minion_dir = '{0}/{1}'.format(dest, fn_)
if not os.path.isdir(minion_dir):
@ -197,44 +243,94 @@ class Client(object):
shutil.copyfile(path, dest)
return dest
def file_local_list(self, env='base'):
def file_local_list(self, saltenv='base', env=None):
'''
List files in the local minion files and localfiles caches
'''
filesdest = os.path.join(self.opts['cachedir'], 'files', env)
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
filesdest = os.path.join(self.opts['cachedir'], 'files', saltenv)
localfilesdest = os.path.join(self.opts['cachedir'], 'localfiles')
fdest = self._file_local_list(filesdest)
ldest = self._file_local_list(localfilesdest)
return sorted(fdest.union(ldest))
def file_list(self, env='base', prefix=''):
def file_list(self, saltenv='base', prefix='', env=None):
'''
This function must be overwritten
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
return []
def dir_list(self, env='base', prefix=''):
def dir_list(self, saltenv='base', prefix='', env=None):
'''
This function must be overwritten
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
return []
def symlink_list(self, env='base', prefix=''):
def symlink_list(self, saltenv='base', prefix='', env=None):
'''
This function must be overwritten
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
return {}
def is_cached(self, path, env='base'):
def is_cached(self, path, saltenv='base', env=None):
'''
Returns the full path to a file if it is cached locally on the minion
otherwise returns a blank string
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
localsfilesdest = os.path.join(
self.opts['cachedir'], 'localfiles', path.lstrip('/'))
filesdest = os.path.join(
self.opts['cachedir'], 'files', env, path.lstrip('salt://'))
self.opts['cachedir'], 'files', saltenv, path.lstrip('salt://'))
if os.path.exists(filesdest):
return filesdest
@ -243,7 +339,7 @@ class Client(object):
return ''
def list_states(self, env):
def list_states(self, saltenv):
'''
Return a list of all available sls modules on the master for a given
environment
@ -253,13 +349,17 @@ class Client(object):
states = []
if limit_traversal:
if env not in self.opts['file_roots']:
log.warning("During an attempt to list states for env {0}, the environment could not be found in the \
configured file roots".format(env))
if saltenv not in self.opts['file_roots']:
log.warning(
'During an attempt to list states for saltenv {0!r}, '
'the environment could not be found in the configured '
'file roots'.format(saltenv)
)
return states
for path in self.opts['file_roots'][env]:
for path in self.opts['file_roots'][saltenv]:
for root, dirs, files in os.walk(path, topdown=True):
log.debug("Searching for states in dirs {0} and files {1}".format(dirs, files))
log.debug('Searching for states in dirs {0} and files '
'{1}'.format(dirs, files))
if not [file.endswith('.sls') for file in files]:
# Use shallow copy so we don't disturb the memory used by os.walk. Otherwise this breaks!
del dirs[:]
@ -278,7 +378,7 @@ class Client(object):
stripped_root = stripped_root.lstrip('.')
states.append(stripped_root + found_file[:-4])
else:
for path in self.file_list(env):
for path in self.file_list(saltenv):
if path.endswith('.sls'):
# is an sls module!
if path.endswith('{0}init.sls'.format('/')):
@ -287,7 +387,7 @@ class Client(object):
states.append(path.replace('/', '.')[:-4])
return states
def get_state(self, sls, env):
def get_state(self, sls, saltenv):
'''
Get a state file from the master and store it in the local minion
cache return the location of the file
@ -296,16 +396,27 @@ class Client(object):
sls = sls.replace('.', '/')
for path in ['salt://{0}.sls'.format(sls),
'/'.join(['salt:/', sls, 'init.sls'])]:
dest = self.cache_file(path, env)
dest = self.cache_file(path, saltenv)
if dest:
return {'source': path, 'dest': dest}
return {}
def get_dir(self, path, dest='', env='base', gzip=None):
def get_dir(self, path, dest='', saltenv='base', gzip=None, env=None):
'''
Get a directory recursively from the salt-master
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
# TODO: We need to get rid of using the string lib in here
ret = []
# Strip trailing slash
path = string.rstrip(self._check_proto(path), '/')
@ -319,7 +430,7 @@ class Client(object):
prefix = separated[0]
# Copy files from master
for fn_ in self.file_list(env):
for fn_ in self.file_list(saltenv):
if fn_.startswith(path):
# Prevent files in "salt://foobar/" (or salt://foo.sh) from
# matching a path of "salt://foo"
@ -335,12 +446,12 @@ class Client(object):
self.get_file(
'salt://{0}'.format(fn_),
'{0}/{1}'.format(dest, minion_relpath),
True, env, gzip
True, saltenv, gzip
)
)
# Replicate empty dirs from master
try:
for fn_ in self.file_list_emptydirs(env):
for fn_ in self.file_list_emptydirs(saltenv):
if fn_.startswith(path):
# Prevent an empty dir "salt://foobar/" from matching a path of
# "salt://foo"
@ -361,13 +472,23 @@ class Client(object):
ret.sort()
return ret
def get_url(self, url, dest, makedirs=False, env='base'):
def get_url(self, url, dest, makedirs=False, saltenv='base', env=None):
'''
Get a single file from a URL.
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
url_data = urlparse(url)
if url_data.scheme == 'salt':
return self.get_file(url, dest, makedirs, env)
return self.get_file(url, dest, makedirs, saltenv)
if dest:
destdir = os.path.dirname(dest)
if not os.path.isdir(destdir):
@ -379,7 +500,7 @@ class Client(object):
dest = salt.utils.path_join(
self.opts['cachedir'],
'extrn_files',
env,
saltenv,
url_data.netloc,
url_data.path
)
@ -419,14 +540,25 @@ class Client(object):
dest,
template='jinja',
makedirs=False,
env='base',
saltenv='base',
env=None,
**kwargs):
'''
Cache a file then process it as a template
'''
kwargs['env'] = env
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
kwargs['saltenv'] = saltenv
url_data = urlparse(url)
sfn = self.cache_file(url, env)
sfn = self.cache_file(url, saltenv)
if not os.path.exists(sfn):
return ''
if template in salt.utils.templates.TEMPLATE_REGISTRY:
@ -451,7 +583,7 @@ class Client(object):
dest = salt.utils.path_join(
self.opts['cachedir'],
'extrn_files',
env,
saltenv,
url_data.netloc,
url_data.path
)
@ -476,18 +608,19 @@ class LocalClient(Client):
def __init__(self, opts):
Client.__init__(self, opts)
def _find_file(self, path, env='base'):
def _find_file(self, path, saltenv='base'):
'''
Locate the file path
'''
fnd = {'path': '',
'rel': ''}
if env not in self.opts['file_roots']:
if saltenv not in self.opts['file_roots']:
return fnd
if path.startswith('|'):
# The path arguments are escaped
path = path[1:]
for root in self.opts['file_roots'][env]:
for root in self.opts['file_roots'][saltenv]:
full = os.path.join(root, path)
if os.path.isfile(full):
fnd['path'] = full
@ -495,27 +628,53 @@ class LocalClient(Client):
return fnd
return fnd
def get_file(self, path, dest='', makedirs=False, env='base', gzip=None):
def get_file(self,
path,
dest='',
makedirs=False,
saltenv='base',
gzip=None,
env=None):
'''
Copies a file from the local files directory into :param:`dest`
gzip compression settings are ignored for local files
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
path = self._check_proto(path)
fnd = self._find_file(path, env)
fnd = self._find_file(path, saltenv)
if not fnd['path']:
return ''
return fnd['path']
def file_list(self, env='base', prefix=''):
def file_list(self, saltenv='base', prefix='', env=None):
'''
Return a list of files in the given environment
with optional relative prefix path to limit directory traversal
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
ret = []
if env not in self.opts['file_roots']:
if saltenv not in self.opts['file_roots']:
return ret
prefix = prefix.strip('/')
for path in self.opts['file_roots'][env]:
for path in self.opts['file_roots'][saltenv]:
for root, dirs, files in os.walk(
os.path.join(path, prefix), followlinks=True
):
@ -528,16 +687,26 @@ class LocalClient(Client):
)
return ret
def file_list_emptydirs(self, env='base', prefix=''):
def file_list_emptydirs(self, saltenv='base', prefix='', env=None):
'''
List the empty dirs in the file_roots
with optional relative prefix path to limit directory traversal
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
ret = []
prefix = prefix.strip('/')
if env not in self.opts['file_roots']:
if saltenv not in self.opts['file_roots']:
return ret
for path in self.opts['file_roots'][env]:
for path in self.opts['file_roots'][saltenv]:
for root, dirs, files in os.walk(
os.path.join(path, prefix), followlinks=True
):
@ -545,28 +714,48 @@ class LocalClient(Client):
ret.append(os.path.relpath(root, path))
return ret
def dir_list(self, env='base', prefix=''):
def dir_list(self, saltenv='base', prefix='', env=None):
'''
List the dirs in the file_roots
with optional relative prefix path to limit directory traversal
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
ret = []
if env not in self.opts['file_roots']:
if saltenv not in self.opts['file_roots']:
return ret
prefix = prefix.strip('/')
for path in self.opts['file_roots'][env]:
for path in self.opts['file_roots'][saltenv]:
for root, dirs, files in os.walk(
os.path.join(path, prefix), followlinks=True
):
ret.append(os.path.relpath(root, path))
return ret
def hash_file(self, path, env='base'):
def hash_file(self, path, saltenv='base', env=None):
'''
Return the hash of a file, to get the hash of a file in the file_roots
prepend the path with salt://<file on server> otherwise, prepend the
file with / for a local file.
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
ret = {}
try:
path = self._check_proto(path)
@ -580,7 +769,7 @@ class LocalClient(Client):
ret['hsum'] = hashlib.md5(ifile.read()).hexdigest()
ret['hash_type'] = 'md5'
return ret
path = self._find_file(path, env)['path']
path = self._find_file(path, saltenv)['path']
if not path:
return {}
ret = {}
@ -590,11 +779,21 @@ class LocalClient(Client):
ret['hash_type'] = self.opts['hash_type']
return ret
def list_env(self, env='base'):
def list_env(self, saltenv='base', env=None):
'''
Return a list of the files in the file server's specified environment
'''
return self.file_list(env)
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
return self.file_list(saltenv)
def master_opts(self):
'''
@ -622,15 +821,15 @@ class LocalClient(Client):
).communicate()[0])
ret = {}
if 'environment' in ndata:
env = ndata['environment']
saltenv = ndata['environment']
else:
env = 'base'
saltenv = 'base'
if 'classes' in ndata:
if isinstance(ndata['classes'], dict):
ret[env] = list(ndata['classes'])
ret[saltenv] = list(ndata['classes'])
elif isinstance(ndata['classes'], list):
ret[env] = ndata['classes']
ret[saltenv] = ndata['classes']
else:
return ret
return ret
@ -665,42 +864,58 @@ class RemoteClient(Client):
self.auth = salt.crypt.SAuth(self.opts)
return _do_transfer()
def get_file(self, path, dest='', makedirs=False, env='base', gzip=None):
def get_file(self,
path,
dest='',
makedirs=False,
saltenv='base',
gzip=None,
env=None):
'''
Get a single file from the salt-master
path must be a salt server location, aka, salt://path/to/file, if
dest is omitted, then the downloaded file will be placed in the minion
cache
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
#-- Hash compare local copy with master and skip download
# if no diference found.
dest2check = dest
if not dest2check:
rel_path = self._check_proto(path)
with self._cache_loc(rel_path, env) as cache_dest:
with self._cache_loc(rel_path, saltenv) as cache_dest:
dest2check = cache_dest
if dest2check and os.path.isfile(dest2check):
hash_local = self.hash_file(dest2check, env)
hash_server = self.hash_file(path, env)
hash_local = self.hash_file(dest2check, saltenv)
hash_server = self.hash_file(path, saltenv)
if hash_local == hash_server:
log.info(
'Fetching file from env {0!r}, ** skipped ** '
'Fetching file from saltenv {0!r}, ** skipped ** '
'latest already in cache {1!r}'.format(
env, path
saltenv, path
)
)
return dest2check
log.debug(
'Fetching file from env {0!r}, ** attempting ** {1!r}'.format(
env, path
'Fetching file from saltenv {0!r}, ** attempting ** {1!r}'.format(
saltenv, path
)
)
d_tries = 0
path = self._check_proto(path)
load = {'path': path,
'env': env,
'saltenv': saltenv,
'cmd': '_serve_file'}
if gzip:
gzip = int(gzip)
@ -728,7 +943,7 @@ class RemoteClient(Client):
if not data['data']:
if not fn_ and data['dest']:
# This is a 0 byte file on the master
with self._cache_loc(data['dest'], env) as cache_dest:
with self._cache_loc(data['dest'], saltenv) as cache_dest:
dest = cache_dest
with salt.utils.fopen(cache_dest, 'wb+') as ofile:
ofile.write(data['data'])
@ -747,7 +962,7 @@ class RemoteClient(Client):
continue
break
if not fn_:
with self._cache_loc(data['dest'], env) as cache_dest:
with self._cache_loc(data['dest'], saltenv) as cache_dest:
dest = cache_dest
# If a directory was formerly cached at this path, then
# remove it to avoid a traceback trying to write the file
@ -762,17 +977,27 @@ class RemoteClient(Client):
if fn_:
fn_.close()
log.info(
'Fetching file from env {0!r}, ** done ** {1!r}'.format(
env, path
'Fetching file from saltenv {0!r}, ** done ** {1!r}'.format(
saltenv, path
)
)
return dest
def file_list(self, env='base', prefix=''):
def file_list(self, saltenv='base', prefix='', env=None):
'''
List the files on the master
'''
load = {'env': env,
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
load = {'saltenv': saltenv,
'prefix': prefix,
'cmd': '_file_list'}
try:
@ -780,11 +1005,21 @@ class RemoteClient(Client):
except SaltReqTimeoutError:
return ''
def file_list_emptydirs(self, env='base', prefix=''):
def file_list_emptydirs(self, saltenv='base', prefix='', env=None):
'''
List the empty dirs on the master
'''
load = {'env': env,
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
load = {'saltenv': saltenv,
'prefix': prefix,
'cmd': '_file_list_emptydirs'}
try:
@ -792,11 +1027,21 @@ class RemoteClient(Client):
except SaltReqTimeoutError:
return ''
def dir_list(self, env='base', prefix=''):
def dir_list(self, saltenv='base', prefix='', env=None):
'''
List the dirs on the master
'''
load = {'env': env,
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
load = {'saltenv': saltenv,
'prefix': prefix,
'cmd': '_dir_list'}
try:
@ -804,11 +1049,11 @@ class RemoteClient(Client):
except SaltReqTimeoutError:
return ''
def symlink_list(self, env='base', prefix=''):
def symlink_list(self, saltenv='base', prefix='', env=None):
'''
List symlinked files and dirs on the master
'''
load = {'env': env,
load = {'saltenv': saltenv,
'prefix': prefix,
'cmd': '_symlink_list'}
try:
@ -816,12 +1061,22 @@ class RemoteClient(Client):
except SaltReqTimeoutError:
return ''
def hash_file(self, path, env='base'):
def hash_file(self, path, saltenv='base', env=None):
'''
Return the hash of a file, to get the hash of a file on the salt
master file server prepend the path with salt://<file on server>
otherwise, prepend the file with / for a local file.
'''
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
try:
path = self._check_proto(path)
except MinionError:
@ -836,18 +1091,18 @@ class RemoteClient(Client):
ret['hash_type'] = 'md5'
return ret
load = {'path': path,
'env': env,
'saltenv': saltenv,
'cmd': '_file_hash'}
try:
return self._crypted_transfer(load)
except SaltReqTimeoutError:
return ''
def list_env(self, env='base'):
def list_env(self, saltenv='base', env=None):
'''
Return a list of the files in the file server's specified environment
'''
load = {'env': env,
load = {'saltenv': saltenv,
'cmd': '_file_list'}
try:
return self._crypted_transfer(load)