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

Reply via email to