Hi, I am still banging my head on this. For a brief moment I thought the problem would be traced to a typo in the source (reapir_denied, reported a few days ago on this list, and hence patched in svn), but I have applied the patch and the problem persists.
The problem is that when the pattern specified in replace_patterns in an edit_line body does not appear in the file at all, it seems none of the classes clauses is triggered. For reference, below is my self-contained example. When the pattern appears in the file, everything works fine, but when the pattern is not there, replace_done is not defined, and thus the line is not appended. Thanks for any help, --Diego body common control { bundlesequence => { "linereplace" }; } bundle agent linereplace { vars: "file" string => "/root/sshd_config"; # Pattern is automatically anchored to the beginning/end of line "pattern" string => "(# *Protocol .*| *Protocol .*1.*)"; "line" string => "Protocol 2"; files: "$(file)" edit_line => replace_or_add("$(pattern)","$(line)"); } bundle edit_line replace_or_add(pattern,line) { replace_patterns: "^${pattern}$" replace_with => value("${line}"), classes => always("replace_done"); insert_lines: replace_done:: "${line}"; } body replace_with value(x) { replace_value => "$(x)"; occurrences => "all"; } body classes always(x) { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } On Tue, Jan 26, 2010 at 4:06 PM, Diego Zamboni <di...@zzamboni.org> wrote: > I am sorry, I didn't realize that at some point we switched off the > list. I'm sending to the list now - thanks for the help. > > --Diego > > > On Tue, Jan 26, 2010 at 2:43 PM, Mark <m...@iu.hio.no> wrote: >> I don't have time to guide you through this, send it to the list >> >> >> Mark >> >> >> On 26 Jan 2010, at 19:50, Diego Zamboni <di...@zzamboni.org> wrote: >> >>> Mark, >>> >>> Thanks again for the nudge in the right direction. Here's my latest >>> attempt, which unfortunately still does not work: >>> >>> >>> bundle edit_line replace_or_add(pattern,line) >>> { >>> replace_patterns: >>> "^${pattern}$" >>> replace_with => value("${line}"), >>> classes => always("replace_done"); >>> >>> insert_lines: >>> replace_done:: >>> "${line}"; >>> >>> } >>> >>> body classes always(x) >>> { >>> promise_repaired => { "$(x)" }; >>> promise_kept => { "$(x)" }; >>> repair_failed => { "$(x)" }; >>> repair_denied => { "$(x)" }; >>> repair_timeout => { "$(x)" }; >>> } >>> >>> If the line exists, whether commented out or not, then the correct >>> thing happens. But if the line does not exist, the class >>> "replace_done" does not get defined anyway, so the insert_lines does >>> not run, even on the second pass. Below is the relevant verbose >>> output. >>> >>> Did I miss some clause in the definition of always()? Or am I missing >>> something else? >>> >>> Thanks again, >>> --Diego >>> >>> >>> cf3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * >>> * >>> cf3 BUNDLE replace_or_add( {'# *Protocol 2,1.*','Protocol 2'} ) >>> cf3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * >>> * >>> cf3 >>> cf3 ? Augment scope replace_or_add with pattern >>> cf3 ? Augment scope replace_or_add with line >>> cf3 ?? Private class context >>> cf3 >>> cf3 >>> cf3 = = = = = = = = = = = = = = = = = = = = = = = = = = = = >>> cf3 insert_lines in bundle replace_or_add >>> cf3 = = = = = = = = = = = = = = = = = = = = = = = = = = = = >>> cf3 >>> cf3 >>> cf3 . . . . . . . . . . . . . . . >>> cf3 Skipping whole next edit promise, as context replace_done is not >>> relevant >>> cf3 . . . . . . . . . . . . . . . >>> cf3 >>> cf3 = = = = = = = = = = = = = = = = = = = = = = = = = = = = >>> cf3 replace_patterns in bundle replace_or_add >>> cf3 = = = = = = = = = = = = = = = = = = = = = = = = = = = = >>> cf3 >>> cf3 >>> cf3 ......................................................... >>> cf3 Promise handle: >>> cf3 Promise made by: ^# *Protocol 2,1.*$ >>> cf3 ......................................................... >>> cf3 >>> cf3 -> Looking at pattern ^# *Protocol 2,1.*$ >>> cf3 ?? Private class context >>> cf3 >>> cf3 >>> cf3 = = = = = = = = = = = = = = = = = = = = = = = = = = = = >>> cf3 insert_lines in bundle replace_or_add >>> cf3 = = = = = = = = = = = = = = = = = = = = = = = = = = = = >>> cf3 >>> cf3 >>> cf3 . . . . . . . . . . . . . . . >>> cf3 Skipping whole next edit promise, as context replace_done is not >>> relevant >>> cf3 . . . . . . . . . . . . . . . >>> >>> >>> On Tue, Jan 26, 2010 at 8:35 AM, Mark Burgess <mark.burg...@iu.hio.no> >>> wrote: >>>> >>>> IN this case, you need to define a class regardless if what happens when >>>> the pattern >>>> replace is made. >>>> >>>> replace_patterns: >>>> >>>> "${p}" >>>> replace_with => value("${l}"), >>>> classes => always("done"); >>>> >>>> insert_lines: >>>> >>>> done:: >>>> >>>> "${l}"; # add only if it doesn't exist >>>> >>>> This should work as long as the $(l) is always a complete line, otherwise >>>> your promise is >>>> ambiguous. What happens if the pattern matches a partial line? cfengine >>>> inserts the line >>>> because there is no complete line matching this expression. Perhaps your >>>> pattern should be >>>> "^$(p)$" ? >>>> >>>> >>>> >>>> Diego Zamboni wrote: >>>>> >>>>> Hi Mark, >>>>> >>>>> Thanks. In fact, my very first attempt was something very similar to >>>>> set_variable_values(), only with a replace_patterns section instead of >>>>> field_edits. The problem I found was that according to normal >>>>> ordering, insert_lines is run before replace_patterns (whereas >>>>> field_edits occurs before insert_lines), which defeats the test with >>>>> the classes. The line is always inserted, regardless of whether the >>>>> replacement works or not, because the negation of a non-existing class >>>>> is true. >>>>> >>>>> Here's that very first version, for reference: >>>>> >>>>> bundle edit_line replace_or_add(p,l) >>>>> { >>>>> replace_patterns: >>>>> "${p}" >>>>> replace_with => value("${l}"), >>>>> classes => if_ok("line_exists"); >>>>> >>>>> insert_lines: >>>>> "${l}" >>>>> ifvarclass => "!line_exists"; >>>>> } >>>>> >>>>> What am I missing? >>>>> >>>>> Thanks again, >>>>> --Diego >>>>> >>>>> >>>>> On Mon, Jan 25, 2010 at 12:29 PM, Mark Burgess <mark.burg...@iu.hio.no> >>>>> wrote: >>>>>> >>>>>> Try looking at the set-variable bundle in the standard library >>>>>> >>>>>> M >>>>>> >>>>>> Diego Zamboni wrote: >>>>>>> >>>>>>> Hi, >>>>>>> >>>>>>> I've been working on putting together an edit_line bundle that does >>>>>>> the following: >>>>>>> >>>>>>> - If a certain pattern exists, replace it with a given string >>>>>>> - If the pattern does not exist, add the line to the file. >>>>>>> >>>>>>> Below is what I came up with, which works, but somehow feels inelegant >>>>>>> because I have to pass it the filename for the check using regline. I >>>>>>> tried doing it by setting different classes in the replace_patterns: >>>>>>> and insert_lines: sections, but could not get it to work. >>>>>>> >>>>>>> I would appreciate any ideas! I am just learning cfengine, so this is >>>>>>> as much an intellectual exercise as something I need (and maybe could >>>>>>> be a useful addition to the stdlib?) >>>>>>> >>>>>>> Thanks, >>>>>>> --Diego >>>>>>> >>>>>>> >>>>>>> bundle edit_line replace_or_add(file,pattern,line) >>>>>>> { >>>>>>> classes: >>>>>>> "lineexists" expression => regline("$(pattern)","$(file)"); >>>>>>> >>>>>>> replace_patterns: >>>>>>> lineexists:: >>>>>>> "${pattern}" >>>>>>> replace_with => value("${line}"); >>>>>>> >>>>>>> insert_lines: >>>>>>> !lineexists:: >>>>>>> "${line}"; >>>>>>> >>>>>>> } >>>>>>> _______________________________________________ >>>>>>> Help-cfengine mailing list >>>>>>> Help-cfengine@cfengine.org >>>>>>> https://cfengine.org/mailman/listinfo/help-cfengine >>>>>> >>>>>> -- >>>>>> Mark Burgess >>>>>> >>>>>> ------------------------------------------------- >>>>>> Professor of Network and System Administration >>>>>> Oslo University College, Norway >>>>>> >>>>>> Personal Web: http://www.iu.hio.no/~mark >>>>>> Office Telf : +47 22453272 >>>>>> ------------------------------------------------- >>>>>> >>>> >>>> -- >>>> Mark Burgess >>>> >>>> ------------------------------------------------- >>>> Professor of Network and System Administration >>>> Oslo University College, Norway >>>> >>>> Personal Web: http://www.iu.hio.no/~mark >>>> Office Telf : +47 22453272 >>>> ------------------------------------------------- >>>> >> > _______________________________________________ Help-cfengine mailing list Help-cfengine@cfengine.org https://cfengine.org/mailman/listinfo/help-cfengine