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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]>
>>> 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 <[email protected]>
>>>>> 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
>>>>>>> [email protected]
>>>>>>> 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
[email protected]
https://cfengine.org/mailman/listinfo/help-cfengine