Diego, this results from a bug that was just fixed in svn 747. No exit status was set for a pattern that was not found. If the pattern was not found, then the promise is considered to be kept.
See new version in SVN. Diego Zamboni wrote: > 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 -- 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