mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Symlink support in file.recurse
This commit is contained in:
parent
e4b794aab3
commit
8025c47ae3
@ -242,15 +242,22 @@ def symlink_list(load):
|
||||
ret = {}
|
||||
if load['env'] not in __opts__['file_roots']:
|
||||
return ret
|
||||
|
||||
for path in __opts__['file_roots'][load['env']]:
|
||||
try:
|
||||
prefix = load['prefix'].strip('/')
|
||||
except KeyError:
|
||||
prefix = ''
|
||||
# No need to follow symlinks here, this is a symlink hunt :-)
|
||||
# If a user has symlinked dirs that contain other symlinks, then setting
|
||||
# the __opts__['fileserver_followsymlinks'] to False will not be desired
|
||||
# unless the user has only 1 deep symlink recursion in the roots.
|
||||
# This causes os.walk to stop at the first symlink encounter.
|
||||
# It is the responsibility of the user to ensure that os.walk does not
|
||||
# encounter an infinite symlink recursion. Python docs warn about this in
|
||||
# the os.walk documentation if followlinks=True. If infinite symlink
|
||||
# is encountered, then the recursion will be passed to the Minion leading
|
||||
# to undesired results.
|
||||
for root, dirs, files in os.walk(os.path.join(path, prefix),
|
||||
followlinks=False):
|
||||
followlinks=__opts__['fileserver_followsymlinks']):
|
||||
for fname in files:
|
||||
if not os.path.islink(os.path.join(root, fname)):
|
||||
continue
|
||||
@ -262,5 +269,8 @@ def symlink_list(load):
|
||||
ret[rel_fn] = os.readlink(os.path.join(root, fname))
|
||||
for dname in dirs:
|
||||
if os.path.islink(os.path.join(root, dname)):
|
||||
ret[dname] = os.readlink(os.path.join(root, dname))
|
||||
ret[os.path.relpath(os.path.join(root,
|
||||
dname),
|
||||
path)] = os.readlink(os.path.join(root,
|
||||
dname))
|
||||
return ret
|
||||
|
@ -1340,6 +1340,7 @@ def recurse(name,
|
||||
group=None,
|
||||
dir_mode=None,
|
||||
file_mode=None,
|
||||
sym_mode=None,
|
||||
template=None,
|
||||
context=None,
|
||||
defaults=None,
|
||||
@ -1349,6 +1350,7 @@ def recurse(name,
|
||||
include_pat=None,
|
||||
exclude_pat=None,
|
||||
maxdepth=None,
|
||||
keep_symlinks=False,
|
||||
**kwargs):
|
||||
'''
|
||||
Recurse through a subdirectory on the master and copy said subdirectory
|
||||
@ -1385,6 +1387,9 @@ def recurse(name,
|
||||
file_mode
|
||||
The permissions mode to set any files created
|
||||
|
||||
sym_mode
|
||||
the permissions mode to set on any symlink created
|
||||
|
||||
template
|
||||
If this setting is applied then the named templating engine will be
|
||||
used to render the downloaded file, currently jinja, mako, and wempy
|
||||
@ -1434,6 +1439,10 @@ def recurse(name,
|
||||
directory
|
||||
- maxdepth: 1 :: Only include files located in the source
|
||||
or immediate subdirectories
|
||||
|
||||
keep_symlinks
|
||||
Keep symlinks when copying from the source. Set this to True if
|
||||
keeping symlinks intact is desired.
|
||||
'''
|
||||
user = _test_owner(kwargs, user=user)
|
||||
ret = {'name': name,
|
||||
@ -1581,10 +1590,20 @@ def recurse(name,
|
||||
#we're searching for things that start with this *directory*.
|
||||
# use '/' since #master only runs on POSIX
|
||||
srcpath = srcpath + '/'
|
||||
# If we are instructed to keep symlinks, then grab the dict of links
|
||||
if keep_symlinks:
|
||||
symlinks = __salt__['cp.list_master_symlinks'](env, srcpath)
|
||||
for fn_ in __salt__['cp.list_master'](env, srcpath):
|
||||
if not fn_.strip():
|
||||
continue
|
||||
|
||||
# Check for symlinked files if symlinks are on the table.
|
||||
# Symlinks will be processed after the entire dir/file structure
|
||||
# is created.
|
||||
if keep_symlinks and symlinks.get(fn_):
|
||||
log.debug('** skipping file ** {0}, it is destined for a symlink'.format(fn_))
|
||||
continue
|
||||
|
||||
# fn_ here is the absolute (from file_roots) source path of
|
||||
# the file to copy from; it is either a normal file or an
|
||||
# empty dir(if include_empty==true).
|
||||
@ -1613,6 +1632,15 @@ def recurse(name,
|
||||
keep.add(dest)
|
||||
|
||||
if dirname not in vdir:
|
||||
# Check for symlinked dirs if symlinks are on the table.
|
||||
# Symlinks will be processed after the entire dir/file structure
|
||||
# is created.
|
||||
_dir = relname.split('/')
|
||||
_dir.pop()
|
||||
_dir = os.path.join(srcpath,'/'.join(_dir))
|
||||
if keep_symlinks and symlinks.get(_dir):
|
||||
log.debug('** skipping dir ** {0}, it is destined for a symlink'.format(_dir))
|
||||
continue
|
||||
# verify the directory perms if they are set
|
||||
manage_directory(dirname)
|
||||
vdir.add(dirname)
|
||||
@ -1628,9 +1656,35 @@ def recurse(name,
|
||||
exclude_pat):
|
||||
continue
|
||||
mdest = os.path.join(name, os.path.relpath(mdir, srcpath))
|
||||
# Check for symlinks that happen to point to an empty dir.
|
||||
# This will be processed along with the other symlinks.
|
||||
if keep_symlinks and symlinks.get(mdir):
|
||||
log.debug('** skipping empty dir ** {0}, it is destined for a symlink'.format(mdir))
|
||||
continue
|
||||
manage_directory(mdest)
|
||||
keep.add(mdest)
|
||||
|
||||
if keep_symlinks:
|
||||
for lname, ltarget in symlinks.items():
|
||||
if not _check_include_exclude(os.path.relpath(lname, srcpath),
|
||||
include_pat,
|
||||
exclude_pat):
|
||||
continue
|
||||
srelpath = os.path.relpath(lname, srcpath)
|
||||
# Force the symlink and makedirs.
|
||||
# This addresses any symlink dependencies
|
||||
# and funky symlink recursion that we may encounter.
|
||||
_ret = symlink(os.path.join(name, srelpath),
|
||||
ltarget,
|
||||
force=True,
|
||||
makedirs=True,
|
||||
user=user,
|
||||
group=group,
|
||||
mode=sym_mode)
|
||||
if not _ret:
|
||||
continue
|
||||
merge_ret(os.path.join(name,srelpath),_ret)
|
||||
|
||||
keep = list(keep)
|
||||
if clean:
|
||||
# TODO: Use directory(clean=True) instead
|
||||
|
Loading…
Reference in New Issue
Block a user