Fix file.recurse w/ clean=True #36802

Fix an endless looping but in file.recurse when clean is set to true.
This patch normalizes paths and handles the root correctly.
This commit is contained in:
Daniel A. Wozniak 2018-03-20 09:58:13 -07:00
parent 19bb725698
commit eb822f5a12
No known key found for this signature in database
GPG key ID: 166B9D2C06C82D61
2 changed files with 56 additions and 17 deletions

View file

@ -263,6 +263,7 @@ For example:
# Import python libs
from __future__ import absolute_import
import collections
import difflib
import itertools
import logging
@ -607,29 +608,34 @@ def _check_file(name):
return ret, msg
def _find_keep_files(root, keep):
'''
Compile a list of valid keep files (and directories).
'''
real_keep = set()
real_keep.add(root)
if isinstance(keep, collections.Iterable):
for fn_ in keep:
if not os.path.isabs(fn_):
continue
fn_ = os.path.normcase(os.path.abspath(fn_))
real_keep.add(fn_)
while True:
fn_ = os.path.abspath(os.path.dirname(fn_))
real_keep.add(fn_)
drive, path = os.path.splitdrive(fn_)
if not path.lstrip(os.sep):
break
return real_keep
def _clean_dir(root, keep, exclude_pat):
'''
Clean out all of the files and directories in a directory (root) while
preserving the files in a list (keep) and part of exclude_pat
'''
real_keep = _find_keep_files_old(root, keep)
removed = set()
real_keep = set()
real_keep.add(root)
if isinstance(keep, list):
for fn_ in keep:
if not os.path.isabs(fn_):
continue
real_keep.add(fn_)
while True:
fn_ = os.path.dirname(fn_)
real_keep.add(fn_)
if fn_ in [
os.sep,
''.join([os.path.splitdrive(fn_)[0], os.sep]),
''.join([os.path.splitdrive(fn_)[0], os.sep, os.sep])
]:
break
def _delete_not_kept(nfn):
if nfn not in real_keep:
# -- check if this is a part of exclude_pat(only). No need to

View file

@ -1843,3 +1843,36 @@ class TestFileState(TestCase, LoaderModuleMockMixin):
run_checks(test=True)
run_checks(strptime_format=fake_strptime_format)
run_checks(strptime_format=fake_strptime_format, test=True)
class TestFindKeepFiles(TestCase):
@skipIf(salt.utils.is_windows(), 'Do not run on Windows')
def test__find_keep_files_unix(self):
keep = filestate._find_keep_files_old(
'/test/parent_folder',
['/test/parent_folder/meh.txt']
)
expected = [
'/',
'/test',
'/test/parent_folder',
'/test/parent_folder/meh.txt',
]
actual = sorted(list(keep))
assert actual == expected, actual
@skipIf(not salt.utils.is_windows(), 'Only run on Windows')
def test__find_keep_files_win32(self):
keep = filestate._find_keep_files(
'c:\\test\\parent_folder',
['C:\\test\\parent_folder\\meh-2.txt']
)
expected = [
'c:\\',
'c:\\test',
'c:\\test\\parent_folder',
'c:\\test\\parent_folder\\meh-2.txt'
]
actual = sorted(list(keep))
assert actual == expected, actual