Thanks, I wasn't aware of the ordering within edit_line, so this information is 
helpful. I guess this order is as good as any given the permutation of 
delete_lines, insert_lines, replace_patterns could make different outcomes.

For some reason I felt that replace_patterns would be higher in the order, as a 
search or fuzzy search for existing text would correct issues first. Then if 
the correct pattern is found, its either deleted, or if not present, inserted. 
The discussion is academic, but still an interesting topic.

Regards, Jim

----- Original Message -----
From: no-re...@cfengine.com
To: help-cfengine@cfengine.org
At:  5/23 17:47:44

Forum: Cfengine Help
Subject: Re: question on replace_patterns and insert_lines
Author: zzamboni
Link to topic: https://cfengine.com/forum/read.php?3,22198,22205#msg-22205

Jim,

The problem is that according to normal ordering, insert_lines runs *before* 
replace_patterns: 
http://www.cfengine.org/manuals/cf3-reference.html#Agent-normal-ordering

So the line from insert_lines is inserted because the line does not yet exist 
in the file (it's still incorrect), and then replace_patterns corrects the 
erroneous line, and you end with two "correct" lines.

The trick is to set a class after replace_patterns runs (regardless of the 
result of the replacement), and to make insert_lines conditional on that class. 
This forces the insert_lines to run only on the second pass (cfengine does up 
to three pases over the promises), which will result in the line being inserted 
*only* if, even after replace_patterns runs, the desired line does not yet 
exist in the file.

I have coded this in a replace_or_add bundle that I have in my personal copy of 
the COPBL https://github.com/zzamboni/cfengine-copbl

bundle edit_line replace_or_add(pattern,line)

 # Replace a pattern in a file with a single line.
 # If the pattern is not found, add the line to the file.
 # The pattern must match the whole line (it is automatically
 # anchored to the start and end of the line) to avoid
 # ambiguity.
 
{
replace_patterns:
  "^${pattern}$"
  replace_with => value("${line}"),
  classes => always("replace_done");

insert_lines:
  replace_done::
  "${line}";
}

body classes always(x)

# Define a class no matter what the outcome of the promise is

{
  promise_repaired => { "$(x)" };
  promise_kept => { "$(x)" };
  repair_failed => { "$(x)" };
  repair_denied => { "$(x)" };
  repair_timeout => { "$(x)" };
}


_______________________________________________
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