On Sat, Nov 20, 2010 at 1:59 PM, Daniel V. Klein <d...@lonewolf.com> wrote: > Michael, you are right and I feel like a fool. Of course - the regex was > wrong!
No need - I have been using regexes forever and still find new ways to get them wrong all the time =) > > But to meet you half way... the \s* matches the spaces the first time, and > the [^0] matches the "1". After that, it replaces the 0 with a 1, and then > you're 100% right. Doh! > > -Dan > > On Nov 19, 2010, at 5:50 PM, Michael Potter wrote: > >> On Sat, Nov 20, 2010 at 6:20 AM, <no-re...@cfengine.com> wrote: >>> Forum: Cfengine Help >>> Subject: replace_patterns bug? >>> Author: babudro >>> Link to topic: https://cfengine.com/forum/read.php?3,19347,19347#msg-19347 >>> >>> Hello Cfengineers. >>> >>> Like Michael Potter's post on 9 November, I am also running into some >>> strange behaviour with replace_patterns. I wonder if someone can spot if I >>> am doing something wrong so I don't file an erroneous bug report. >>> >>> All I am trying to do is replace a parameter line in a file. I created >>> this rule to toggle the setting: >>> >>> >>> bundle edit_line yum_plugins(x) { >>> replace_patterns: >>> "^enabled\s*=\s*[^$(x)]" replace_with => value("enabled = $(x)"); >>> } >>> >>> >>> The idea is that if I pass x=0 then it searches for "enabled" not equal to >>> zero and, if it finds a match, changes it to be zero. >>> >>> When I run this promise, I get this: >>> >>> >>> -> Promised replacement "enabled = 00000000000000000000" on line "enabled >>> = 1" for pattern "^enabled\s*=\s*[^0]" is not convergent while editing >>> /etc/yum/pluginconf.d/rhnplugin.conf >>> Because the regular expression "^enabled\s*=\s*[^0]" still matches the >>> replacement string "enabled = 00000000000000000000" >>> Promise (version 8) belongs to bundle 'yum_plugins' in file './yum.cf' near >>> line 215 >>> -> Promised replacement "enabled = 00000000000000000000" on line "enabled >>> = 1" for pattern "^enabled\s*=\s*[^0]" is not convergent while editing >>> /etc/yum/pluginconf.d/rhnplugin.conf >>> >>> >>> How weird is that? >> >> Replace patterns in continually evaluated until it reaches a state of >> convergence, i.e. the pattern to be replaced no longer exists in the >> file. It does not just stop after the first replace - this has always >> been the case and is not new to 3.1.0. My issue report was that >> insert_lines should not insert multiple times - this is new to 3.1.0. >> >>> >>> I understand how "enabled = 00" does not match the pattern >>> "^enabled\s*=\s*[^0]" since I only have a single zero, but how did it ever >>> get that second >(and third and fourth &c.) zero? It should have made the >>> first replacement and then stopped since the match is no longer true. >> >> How? First, you need to understand the regular expressions always >> *attempt* to match. In your case, the \s* after the = matches nothing, >> then the [^0] matches a space. Then that string is replaced with your >> replacement pattern, hence you get an infinite loop of zeroed being >> created. >> >>> >>> If I put a dollar-sign at the end of the match string, it works. But I >>> shouldn't have to do that. >> >> Actually, you do need to write your regex to ensure that it no longer >> matches after the first replacement. Putting a $ at the end is one way >> to do that, because now you are *forcing* the regex parser to compare >> 0 to [^0] (which obviously doesn't match) - so the whole expression >> doesnt match and the replace terminates. >> >> There are probably other ways you can write the regex to get the same >> effect - but whatever you do it is your responsibility to ensure the >> regex does not match after the replace_patterns is applied. >> >>> >>> Am I missing something? >>> >>> Here is a self-contained policy file to demonstrate this apparent bug: >>> >>> >>> body common control { >>> bundlesequence => { "yum" }; >>> } >>> bundle agent yum { >>> files: >>> redhat:: >>> "/tmp/test.conf" >>> comment => "Demonstrate pattern bug", >>> create => "false", >>> edit_line => yum_plugins("0"); >>> >>> reports: >>> plugins_toggled:: >>> "Toggled 'enabled' flag in test.conf."; >>> } >>> bundle edit_line yum_plugins(x) { >>> replace_patterns: >>> "^enabled\s*=\s*[^$(x)]" replace_with => value("enabled = $(x)"); >>> } >>> body replace_with value(x) { >>> replace_value => "$(x)"; >>> occurrences => "all"; >>> } >>> >>> # vim:ts=2 >>> >>> >>> Create the file /tmp/test.conf with just this one line: >>> >>> >>> enabled = 1 >>> >>> >>> Now watch it explode: >>> >>> >>> $ cf-agent -f ./pattern_bug.cf >>> -> Promised replacement "enabled = 00000000000000000000" on line "enabled >>> = 1" for pattern "^enabled\s*=\s*[^0]" is not convergent while editing >>> /tmp/test.conf >>> I: Made in version 'not specified' of './pattern_bug.cf' near line 18 >>> Because the regular expression "^enabled\s*=\s*[^0]" still matches the >>> replacement string "enabled = 00000000000000000000" >>> Promise (version not specified) belongs to bundle 'yum_plugins' in file >>> './pattern_bug.cf' near line 18 >>> -> Promised replacement "enabled = 00000000000000000000" on line "enabled >>> = 1" for pattern "^enabled\s*=\s*[^0]" is not convergent while editing >>> /tmp/test.conf >>> I: Made in version 'not specified' of './pattern_bug.cf' near line 18 >>> Because the regular expression "^enabled\s*=\s*[^0]" still matches the >>> replacement string "enabled = 00000000000000000000" >>> Promise (version not specified) belongs to bundle 'yum_plugins' in file >>> './pattern_bug.cf' near line 18 >>> -> Promised replacement "enabled = 00000000000000000000" on line "enabled >>> = 1" for pattern "^enabled\s*=\s*[^0]" is not convergent while editing >>> /tmp/test.conf >>> I: Made in version 'not specified' of './pattern_bug.cf' near line 18 >>> Because the regular expression "^enabled\s*=\s*[^0]" still matches the >>> replacement string "enabled = 00000000000000000000" >>> Promise (version not specified) belongs to bundle 'yum_plugins' in file >>> './pattern_bug.cf' near line 18 >>> >>> >>> _______________________________________________ >>> Help-cfengine mailing list >>> Help-cfengine@cfengine.org >>> https://cfengine.org/mailman/listinfo/help-cfengine >>> >> _______________________________________________ >> Help-cfengine mailing list >> Help-cfengine@cfengine.org >> https://cfengine.org/mailman/listinfo/help-cfengine > > _______________________________________________ Help-cfengine mailing list Help-cfengine@cfengine.org https://cfengine.org/mailman/listinfo/help-cfengine