Hi Berthold,
Thanks for letting us know.
Can you please make a self contained policy that reproduces the behavior? I don't recall any changes to the difference() function in the recent past. If there is an unintended behavior change here there is little time to address it before the next release.
until now I wasn't able to reproduce the problem with a separate script in an isolated environment. I think I'm still missing something. Perhaps I have to rebuild the complete directory structure of our setup.
Well, that's unfortunate.
Looking at it again the output from the working version said …
verbose: Skipping iteration since variable 'dirs_to_delete' resolves to an empty list
That doesn't have far to trace. It comes from dirs_found (derived from findfiles) and dirs_expected (derived from maplist)
There was this fix to findfiles() in 3.24, but it only affected windows as far as I know:
(ENT-11923)
Hey Berthold,
That seems like it's related to this blog post about change in behavior for findfiles() (https://cfengine.com/blog/2025/change-in-behavior-findfiles/).
But, that post doesn't mention any intent to alter the trailing slash that signals directory. I am not sure if it was intentional or not.
This policy demonstrates the difference:
bundle agent main { methods: "init"; "test"; "check"; reports: inform_mode:: "CFEngine: $(sys.cf_version)"; } bundle agent init { vars: "testdir" string => "/tmp/testdir"; "subdirs" slist => { "a", "b", "c" }; files: "$(testdir)/$(subdirs)/." create => "true"; } bundle agent test { vars: "found" slist => { findfiles( "$(init.testdir)/*/" ) }; } bundle agent check { vars: "foundtype[$(test.found)]" string => filestat( $(test.found), "type"); "found_types" slist => getvalues( foundtype ); "founddir[$(test.found)]" string => "$(foundtype[$(test.found)])", if => strcmp( "$(foundtype[$(test.found)])", "directory" ); "found_dirs" slist => getindices( founddir ); classes: "every_finding_has_trailing_slash" expression => every( ".*\/$", @(test.found) ); "every_finding_is_directory" expression => every( "directory", @(found_types) ); "every_found_directory_ends_trailing_slash" expression => every( ".*\/$", @(found_dirs) ); reports: "Every findfiles() result has trailing slash" if => "every_finding_has_trailing_slash"; "Found: $(test.found)"; "Every findfiles() result is a directory" if => "every_finding_is_directory"; "Type $(test.found) = $(foundtype[$(test.found)])"; "Every directory returned by findfiles() has trailing slash" if => "every_found_directory_ends_trailing_slash"; }
# cf-agent -Kf ./t.cf --inform R: Every findfiles() result has trailing slash R: Found: /tmp/testdir/a/ R: Found: /tmp/testdir/b/ R: Found: /tmp/testdir/c/ R: Every findfiles() result is a directory R: Type /tmp/testdir/a/ = directory R: Type /tmp/testdir/b/ = directory R: Type /tmp/testdir/c/ = directory R: Every directory returned by findfiles() has trailing slash R: CFEngine: 3.21.8
# cf-agent -KIf ./t.cf info: Created directory '/tmp/testdir/a/.', mode 0700 info: Created directory '/tmp/testdir/b/.', mode 0700 info: Created directory '/tmp/testdir/c/.', mode 0700 R: Found: /tmp/testdir/a R: Found: /tmp/testdir/b R: Found: /tmp/testdir/c R: Every findfiles() result is a directory R: Type /tmp/testdir/a = directory R: Type /tmp/testdir/b = directory R: Type /tmp/testdir/c = directory R: CFEngine: 3.24.0