I believe the problem is this expression:

"^(smtp_host)\s+.*$" replace_with => value("$(match.1) $(smtp)"),

Because you use a .* after the whitespace, the regex will continue to match
after any replacement occurs.

Try using a negative lookahead assertion:

"^(smtp_host)\s+(?!$(smtp))$"

This will ensure the pattern only matches when smtp_host is *not* followed
by $(smtp), so after the first replacement occurs, the regex will no longer
match and will be convergent.

On Wed, Dec 8, 2010 at 9:13 AM, Daniel Dehennin <
daniel.dehen...@baby-gnu.org> wrote:

> Hello,
>
> I have some troubles with edit_lines convergence:
>
> #v+
> body common control
> {
>
>    bundlesequence => { "filetest" };
>    version => "0.0.3";
> }
>
> bundle agent filetest
> {
>
>    vars:
>
>        "smtp" string => "smtp.example.net";
>    files:
>
>        "/tmp/main.cf"
>            create => "true",
>            edit_line => fix_smtp_host("$(smtp)"),
>            comment => "smpt_host must be $(smtp)";
>
>
>    reports:
>        SMTPHostFixed::
>            "I reload the SMTP server";
> }
>
> bundle edit_line fix_smtp_host(smtp)
> {
>    replace_patterns:
>        any::
>            "^(smtp_host)\s+.*$" replace_with => value("$(match.1)
> $(smtp)"),
>                                classes => if_ok("SMTPHostOK",
> "SMTPHostFixed"),
>                                comment => "Replace smtp_host if any";
>
>    insert_lines:
>            "smtp_host $(smtp)",
>                       classes => if_ok("SMTPHostOK", "SMTPHostFixed"),
>                       comment => "Add smtp_host if none";
> }
>
> body replace_with value(v)
> {
>    replace_value => "$(v)";
>    occurrences => "all";
> }
>
> body classes if_ok(notchanged, changed)
> {
>    promise_kept => { "$(notchanged)" };
>    promise_repaired => { "$(changed)" };
> }
> #v-
>
> Verbose output produce:
> #v+
> cf3     Promise handle:
> cf3     Promise made by: ^(smtp_host)\s+.*$
> cf3
> cf3     Comment:  Replace smtp_host if any
> cf3     .........................................................
> cf3
> cf3  -> Looking at pattern ^(smtp_host)\s+.*$
> cf3  -> Verifying replacement of "^(smtp_host)\s+.*$" with "smtp_host
> smtp.example.net" (2)
> cf3  -> Verifying replacement of "^(smtp_host)\s+.*$" with "smtp_host
> smtp.example.net" (3)
> [...]
> cf3  -> Verifying replacement of "^(smtp_host)\s+.*$" with "smtp_host
> smtp.example.net" (21)
> cf3  !! Too many replacements on this line
> cf3  -> Replaced pattern "^(smtp_host)\s+.*$" in /tmp/main.cf
> cf3  ?> defining promise result class SMTPHostFixed
> cf3  -> << (22)"smtp_host smtp.example.net"
> cf3  -> >> (22)"smtp_host smtp.example.net"
> cf3  -> Promised replacement "smtp_host smtp.example.net" for pattern
> "^(smtp_host)\s+.*$" is not properly convergent while editing /tmp/main.cf
> cf3 Because the regular expression "^(smtp_host)\s+.*$" still matches the
> end-state replacement string "smtp_host smtp.example.net"
> cf3 Promise (version 0.0.3) belongs to bundle 'fix_smtp_host' in file
> '/home/dad/.cfagent/inputs/promises.cf' near line 31
> cf3 Comment: Replace smtp_host if any
> #v-
>
> The pattern to replace must not match the replacement string, I think
> that if I use delete_lines/insert_lines I will always reload my SMTP
> server.
>
> I want to
> - insert the line if it's not defined
> - replace previous setting with the new one
>
> If I change the "smtp" variable, I end with two "smtp_host" lines in my
> file.
>
> Regards.
> --
> Daniel Dehennin
> Récupérer ma clef GPG:
> gpg --keyserver pgp.mit.edu --recv-keys 0x6A2540D1
>
> _______________________________________________
> 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

Reply via email to