Hi Luke,

On Wed, Oct 13, 2010 at 10:46 AM, Luke Bigum <[email protected]>wrote:

> Hi list,
>
>
>
> I have a problem with editing/appending to a line in a file where the lense
> describes nodes in the file as only numbers like /etc/hosts:
>
>
>
> [r...@infrastructure-svn ~]# augtool
>
> augtool> print /files/etc/hosts
>
> /files/etc/hosts/1
>
> /files/etc/hosts/1/ipaddr = "127.0.0.1"
>
> /files/etc/hosts/1/canonical = "localhost.localdomain"
>
> /files/etc/hosts/1/alias = "localhost"
>
> …
>
> /files/etc/hosts/4
>
> /files/etc/hosts/4/ipaddr = "10.10.10.10"
>
> /files/etc/hosts/4/canonical = "puppet"
>
>
>
> What I am trying to do is use a ‘set’ command to either edit an existing
> line in the file (based on a pattern match on a ‘module’ node) or if one
> does not exist, create a new one. So basically it’s an edit operation which
> appends if it doesn’t exist. This can be done one other types of files where
> base node name is not just a number, /etc/exports for example is “keyed” on
> the node name ‘dir’:
>
>
>
> set dir[.='/home’] /home
>
set dir[.='/home’]/client 10.10.10.10
>
> set dir[.='/home’]/client/option[1] ro
>
>
>
> In this way the first ‘set’ command self-defines if it doesn’t already
> exist
>

That's not the way augeas works. Here is something you could do:

# Define a variable $s which contains /files/etc/exports only if there is
not entry for /home
defvar s /files/etc/exports[count(dir[.="/home"])=0]
# Insert a new dir node for this variable $s. This will fail if there is
already a node for /home, but it's ok
ins dir after $s/dir[last()]
# Set this new node to /home. It won't do anything if $s is empty. After
this step, you're sure to have a node for /home, whether it existed before
or you just created it
set $s/dir[last()] "/home"
# Define a variable $h which contains the path to the /home node (which must
exist now)
defvar h /files/etc/exports/dir[.="/home"]
# Set the client value
set $h/client "10.10.10.10"
# Define a variable $n which contains $h/client only if there is no option
set yet
defvar n $h/client[count(option)=0]
# Define new option as ro
set $n/option "ro"
# Define a variable $p which contains $h/client only if there is no "ro"
option already set (other cases than this one and the previous ones don't
matter, since "ro" is already set)
defvar p $h/client[count(option[.="ro"])=0]
# Insert an option ro after the last option of $p and set it to ro
ins option after $p/option[last()]
set $p/option[last()] ro

I reckon this is a bit complicated, but that's the only way I can think of
without using anything else than Augeas (you could use conditionals with
C/python/ruby/bash/etc. using the lib otherwise).



> , or it edits an existing line. I’d like to achieve the same thing in files
> where nodes are described like array indexes, but I can’t figure out how.
> Here’s a few examples I’ve tried:
>
>
>
> augtool> set /files/etc/hosts/*/ipaddr[.='10.44.220.23'] 10.44.220.23
>
> Failed
>
> augtool> set /files/etc/hosts/*[ipaddr='10.44.220.23']/ipaddr 10.44.220.23
>
> Failed
>

This is the same issue, and requires the same kind of trick (using variables
with conditionals in the Xpath expression).


Raphaël
_______________________________________________
augeas-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/augeas-devel

Reply via email to