Fix file.directory with clean=true and require_in with states ID

In order to know which files need to be cleaned up, a file.directory state
looks at its requirements.
Previously, it only looked at the name attribute of the required state and
supposed it was the name of the file to keep within this directory. It's
not completely right, as a requirement can also be made against a state ID,
in which case the 'name' attribute of the required state then have to be
used.

Fix #8646
This commit is contained in:
Jonathan Ballet 2015-10-07 14:53:04 +02:00
parent 0d391275de
commit 4ff9f4be2a
2 changed files with 43 additions and 3 deletions

View file

@ -371,10 +371,12 @@ def _gen_keep_files(name, require, walk_d=None):
required_files = [comp for comp in require if 'file' in comp]
for comp in required_files:
for low in __lowstate__:
if low['name'] == comp['file']:
# A requirement should match either the ID and the name of
# another state.
if low['name'] == comp['file'] or low['__id__'] == comp['file']:
fn = low['name']
if os.path.isdir(comp['file']):
if _is_child(comp['file'], name):
if os.path.isdir(fn):
if _is_child(fn, name):
if walk_d:
walk_ret = set()
_process_by_walk_d(fn, walk_ret)

View file

@ -529,6 +529,44 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
self.assertFalse(os.path.exists(wrong_file))
def test_directory_clean_require_with_name(self):
'''
file.directory test with clean=True and require with a file state
relatively to the state's name, not its ID.
'''
state_name = 'file-FileTest-test_directory_clean_require_in_with_id'
state_filename = state_name + '.sls'
state_file = os.path.join(STATE_DIR, state_filename)
directory = tempfile.mkdtemp()
self.addCleanup(lambda: shutil.rmtree(directory))
wrong_file = os.path.join(directory, "wrong")
with open(wrong_file, "w") as fp:
fp.write("foo")
good_file = os.path.join(directory, "bar")
with salt.utils.fopen(state_file, 'w') as fp:
self.addCleanup(lambda: os.remove(state_file))
fp.write(textwrap.dedent('''\
some_dir:
file.directory:
- name: {directory}
- clean: true
- require:
# This requirement refers to the name of the following
# state, not its ID.
- file: {good_file}
some_file:
file.managed:
- name: {good_file}
'''.format(directory=directory, good_file=good_file)))
ret = self.run_function('state.sls', [state_name])
self.assertTrue(os.path.exists(good_file))
self.assertFalse(os.path.exists(wrong_file))
def test_recurse(self):
'''
file.recurse