[augeas-devel] set for multiple entries?

David Lutterkort lutter at redhat.com
Tue Mar 16 00:40:46 UTC 2010


On Sun, 2010-03-14 at 10:48 +0100, Frederik Wagner wrote:
> On Fri, Feb 26, 2010 at 12:43 AM, David Lutterkort <lutter at redhat.com> wrote:
> > On Thu, 2010-02-25 at 19:19 +0100, Frederik Wagner wrote:
> >> Hi .*,
> >>
> >> I would like to append definitions for the console to _all_ kernel
> >> lines ins the grub configuration. Is there a way to do that without
> >> knowing howmany entries there are? E.g. using something like:
> >>
> >> augtool> set /files/boot/grub/menu.lst/title[*]/kernel/console[1] ttyS0
> >> or
> >> augtool> set /files/boot/grub/menu.lst/*/kernel/console[1] ttyS1
> >>
> >> I.e. so every title entry containing a kernel line would get
> >> "console=..." parameters appended.
> >> It is not working like I wrote, but there hopefully is away (btw. I'm
> >> using augeas normally through puppet!).
> 
> Hi David,
> 
> > There's actually no way to do that through the API in one call - you can
> > do it, e.g. in Ruby with something like
> >
> >        aug.match("/files/boot/grub/menu.lst/*/kernel/console").each do
> >        |p|
> >          aug.set(p, "ttyS1")
> >        end
> >
> > It would not be very hard to add a aug_set_all call to the API (it would
> > be a slight variation on aug_set in augeas.c) If you feel up to it, I'd
> > happily take a patch ;)
> 
> while playing around in the code, it os actually quite simple as long
> the node (in the example '../console') exists. When the node or the
> path to the node does not exists (there might be kernel settings which
> do not yet have a 'console' parameter), the match won't find them and
> the aug_set() will not create the node.

Aah, yes, you are right - I only thought about it in terms of already
existing nodes. In that case, it would be best to have the user tell you
which part of the path should already exist, and what part to set. In
Rubyesque pseudo code, something like

        def setm(base, child, value)
          aug.match(base).each do |p|
            aug.set(p + b, value)
          end
        end
        
Attached is a completely untested patch that should include the guts of
a 'set multiple' nodes API call. It does a slight variation on the
above: inside the match loop, it checks if there already are one or more
nodes matching p+b; if so, it sets each of them, if not it creates a new
one.

What's missing is exposing this call in augtool and the language
bindings - for puppet, that would mean to enhance ruby-augeas.

> The way to do this - as far as I understand - would be to somehow
> delete the last node in the path/pattern (the node which value hast to
> be set), match for the resulting patj and do a set on each match+node
> to set.  But for this I'm lost in the code, I don't want to introduce
> arbitrary string manipulation in augeas.c ;-)
> I'm anyway not sure, if the result would allow for all matching
> operation, e.g. matches on the last part of the path, like
> "/file/some/path/*[somematch]"

I agree with your analysis - and that it would be way too complicated to
get right in a language binding.

> Including this in ruby or the ruby API seems more simple, but since I
> would like to use it in puppet, I don't want to make a change in all
> the interfaces for a 'dirty hack'.

Let me know how much you can do with this patch. Would be great if you
could enhance it with a test or two, either by exposing it in augtool
and writing a shell script that tests it, or with a test written in C.
Once we have that, I'll commit all that.

David
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Add-aug_setm-to-API.patch
Type: text/x-patch
Size: 3531 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20100315/2aa0a209/attachment.bin>


More information about the augeas-devel mailing list