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

Reply via email to