[augeas-devel] Re: using defnode to add new nodes

David Lutterkort lutter at redhat.com
Tue Jun 16 18:12:27 UTC 2009


On Tue, 2009-06-16 at 11:08 +0200, Kjetil Torgrim Homme wrote:
> David Lutterkort <lutter at redhat.com> writes:
> 
> > On Mon, 2009-06-15 at 12:50 +0200, Kjetil Torgrim Homme wrote:
> >> I was trying to use defnode as a simple way to declare state
> >> idempotently, and defnode seems to be the ticket.  let's say I wanted
> >> to add a new entry in /etc/services
> >> 
> >>   defnode svc '/files/etc/services/service-name[. = "foo" and protocol = "tcp"]' foo
> >>   set $svc/port 4711
> >>   set $svc/protocol tcp
> >> 
> >> this works fine for known services, but when adding a new entry, it
> >> fails.
> >
> > The problem is that 'defnode var path value' is roughly equivalent to
> >
> >         if !exists(path)
> >           set path value
> >         end
> >         defvar var path
> >
> > The path you use will only find the service-name node for 'foo' if it
> > has a protocol child set to 'tcp' - but the set that defnode does, does
> > not create a protocol child. With that, you wind up with a defvar with a
> > path that matches no nodes, and var contains the empty node set.
> 
> exactly.  the bug is that it doesn't add the new node to the node set.
> after all, it's not a dynamic evaluation, so adding it statically
> should work.

Variables are not changed once they have been defined - i.e., when you
do 'defvar var expr', expr is evaluated and the result is assigned to
var (just like in any other language). After that, the value of var is
not changed.

> I dare say it's expected and wanted behaviour.  an
> orphaned node is not very useful.

The node isn't orphaned, it's in the tree, it's just that the path
expression you use in defnode doesn't match anything, even after the
set, since the new node doesn't have a 'protocol' child yet.

> I do not want "if" statements, "if" statements are fragile and you can
> easily get uncovered cases etc.  I want a declarative language, and
> defnode + XPath is *almost* there for many uses.

I don't think that defnode is a good base for a declarative way to
modify the tree. For that, you want a way to say "here is subtree and
the place where it should appear in the overall tree"; the trouble in
general lies with defining the place where the subtree should appear -
in your example, that place depends on two nodes (service-name = 'foo'
and service-name/protocol = 'tcp'), but there's no reason why that
couldn't depend on even more complex conditions on the structure of the
tree.

David






More information about the augeas-devel mailing list